diff --git a/.gitignore b/.gitignore
index 2ddde2a..ac246c1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,73 +1,37 @@
-# Miscellaneous
-*.class
-*.log
-*.pyc
-*.swp
-.DS_Store
-.atom/
-.buildlog/
-.history
-.svn/
-
-# 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/
-.dart_tool/
-.flutter-plugins
-.packages
-.pub-cache/
-.pub/
-/build/
-
-# Android related
-**/android/**/gradle-wrapper.jar
-**/android/.gradle
-**/android/captures/
-**/android/gradlew
-**/android/gradlew.bat
-**/android/local.properties
-**/android/**/GeneratedPluginRegistrant.java
-
-# iOS/XCode related
-**/ios/**/*.mode1v3
-**/ios/**/*.mode2v3
-**/ios/**/*.moved-aside
-**/ios/**/*.pbxuser
-**/ios/**/*.perspectivev3
-**/ios/**/*sync/
-**/ios/**/.sconsign.dblite
-**/ios/**/.tags*
-**/ios/**/.vagrant/
-**/ios/**/DerivedData/
-**/ios/**/Icon?
-**/ios/**/Pods/
-**/ios/**/.symlinks/
-**/ios/**/profile
-**/ios/**/xcuserdata
-**/ios/.generated/
-**/ios/Flutter/App.framework
-**/ios/Flutter/Flutter.framework
-**/ios/Flutter/Generated.xcconfig
-**/ios/Flutter/app.flx
-**/ios/Flutter/app.zip
-**/ios/Flutter/flutter_assets/
-**/ios/Flutter/flutter_export_environment.sh
-**/ios/ServiceDefinitions.json
-**/ios/Runner/GeneratedPluginRegistrant.*
-
-# Exceptions to above rules.
-!**/ios/**/default.mode1v3
-!**/ios/**/default.mode2v3
-!**/ios/**/default.pbxuser
-!**/ios/**/default.perspectivev3
-!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# 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/
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Exceptions to above rules.
+!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
diff --git a/.metadata b/.metadata
index 386075d..5d1241e 100644
--- a/.metadata
+++ b/.metadata
@@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.
version:
- revision: 1aedbb1835bd6eb44550293d57d4d124f19901f0
+ revision: 9f5ff2306bb3e30b2b98eee79cd231b1336f41f4
channel: stable
project_type: app
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ 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.
+
+
+ Copyright (C)
+
+ 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 .
+
+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:
+
+ Copyright (C)
+ 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
+.
+
+ 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
+.
diff --git a/README.md b/README.md
index ace5de4..7bafa0d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,3 @@
-# Epilyon
-
-Keeping EPITA students organized.
+# Epilyon
+
+Keeping EPITA students organized
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100644
index 0000000..0b9e049
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,7 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 97ef0ce..d3f3b00 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,67 +1,66 @@
-def localProperties = new Properties()
-def localPropertiesFile = rootProject.file('local.properties')
-if (localPropertiesFile.exists()) {
- localPropertiesFile.withReader('UTF-8') { reader ->
- localProperties.load(reader)
- }
-}
-
-def flutterRoot = localProperties.getProperty('flutter.sdk')
-if (flutterRoot == null) {
- throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
-}
-
-def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
-if (flutterVersionCode == null) {
- flutterVersionCode = '1'
-}
-
-def flutterVersionName = localProperties.getProperty('flutter.versionName')
-if (flutterVersionName == null) {
- flutterVersionName = '1.0'
-}
-
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
-
-android {
- compileSdkVersion 28
-
- sourceSets {
- main.java.srcDirs += 'src/main/kotlin'
- }
-
- lintOptions {
- disable 'InvalidPackage'
- }
-
- defaultConfig {
- // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
- applicationId "fr.litarvan.epilyon"
- minSdkVersion 16
- targetSdkVersion 28
- versionCode flutterVersionCode.toInteger()
- versionName flutterVersionName
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
-
- buildTypes {
- release {
- // TODO: Add your own signing config for the release build.
- // Signing with the debug keys for now, so `flutter run --release` works.
- signingConfig signingConfigs.debug
- }
- }
-}
-
-flutter {
- source '../..'
-}
-
-dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
-}
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 28
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ defaultConfig {
+ applicationId "com.litarvan.epilyon"
+ minSdkVersion 16
+ targetSdkVersion 28
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+}
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
index 7b71450..28c2efb 100644
--- a/android/app/src/debug/AndroidManifest.xml
+++ b/android/app/src/debug/AndroidManifest.xml
@@ -1,7 +1,7 @@
-
-
-
-
+
+
+
+
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 7bf9e78..98dad7c 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -1,33 +1,30 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/kotlin/com/litarvan/epilyon/MainActivity.kt b/android/app/src/main/kotlin/com/litarvan/epilyon/MainActivity.kt
new file mode 100644
index 0000000..c299c78
--- /dev/null
+++ b/android/app/src/main/kotlin/com/litarvan/epilyon/MainActivity.kt
@@ -0,0 +1,12 @@
+package com.litarvan.epilyon
+
+import androidx.annotation.NonNull;
+import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
+import io.flutter.plugins.GeneratedPluginRegistrant
+
+class MainActivity: FlutterActivity() {
+ override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
+ GeneratedPluginRegistrant.registerWith(flutterEngine);
+ }
+}
diff --git a/android/app/src/main/kotlin/fr/litarvan/epilyon/MainActivity.kt b/android/app/src/main/kotlin/fr/litarvan/epilyon/MainActivity.kt
deleted file mode 100644
index a820c2e..0000000
--- a/android/app/src/main/kotlin/fr/litarvan/epilyon/MainActivity.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package fr.litarvan.epilyon
-
-import android.os.Bundle
-
-import io.flutter.app.FlutterActivity
-import io.flutter.plugins.GeneratedPluginRegistrant
-
-class MainActivity: FlutterActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- GeneratedPluginRegistrant.registerWith(this)
- }
-}
diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml
index 304732f..8403758 100644
--- a/android/app/src/main/res/drawable/launch_background.xml
+++ b/android/app/src/main/res/drawable/launch_background.xml
@@ -1,12 +1,12 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
index 00fa441..4c57322 100644
--- a/android/app/src/main/res/values/styles.xml
+++ b/android/app/src/main/res/values/styles.xml
@@ -1,8 +1,8 @@
-
-
-
-
+
+
+
+
diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml
index 7b71450..28c2efb 100644
--- a/android/app/src/profile/AndroidManifest.xml
+++ b/android/app/src/profile/AndroidManifest.xml
@@ -1,7 +1,7 @@
-
-
-
-
+
+
+
+
diff --git a/android/build.gradle b/android/build.gradle
index b7faad8..7cad156 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,31 +1,31 @@
-buildscript {
- ext.kotlin_version = '1.2.71'
- repositories {
- google()
- jcenter()
- }
-
- dependencies {
- classpath 'com.android.tools.build:gradle:3.2.1'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
-allprojects {
- repositories {
- google()
- jcenter()
- }
-}
-
-rootProject.buildDir = '../build'
-subprojects {
- project.buildDir = "${rootProject.buildDir}/${project.name}"
-}
-subprojects {
- project.evaluationDependsOn(':app')
-}
-
-task clean(type: Delete) {
- delete rootProject.buildDir
-}
+buildscript {
+ ext.kotlin_version = '1.3.50'
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/android/gradle.properties b/android/gradle.properties
index 2bd6f4f..74c1d92 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,2 +1,4 @@
-org.gradle.jvmargs=-Xmx1536M
-
+org.gradle.jvmargs=-Xmx1536M
+android.enableR8=true
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index 2819f02..31afd70 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Jun 23 08:50:38 CEST 2017
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/android/settings.gradle b/android/settings.gradle
index 5a2f14f..4f14f8e 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,15 +1,15 @@
-include ':app'
-
-def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
-
-def plugins = new Properties()
-def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
-if (pluginsFile.exists()) {
- pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
-}
-
-plugins.each { name, path ->
- def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
- include ":$name"
- project(":$name").projectDir = pluginDirectory
-}
+include ':app'
+
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+
+def plugins = new Properties()
+def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
+if (pluginsFile.exists()) {
+ pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
+}
+
+plugins.each { name, path ->
+ def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
+ include ":$name"
+ project(":$name").projectDir = pluginDirectory
+}
diff --git a/assets/fonts/Lato_SemiBold.ttf b/assets/fonts/Lato_SemiBold.ttf
new file mode 100644
index 0000000..96df47c
Binary files /dev/null and b/assets/fonts/Lato_SemiBold.ttf differ
diff --git a/assets/fonts/Lato_SemiBold_Italic.ttf b/assets/fonts/Lato_SemiBold_Italic.ttf
new file mode 100644
index 0000000..81a8faa
Binary files /dev/null and b/assets/fonts/Lato_SemiBold_Italic.ttf differ
diff --git a/assets/icons/arrow_drop_down.svg b/assets/icons/arrow_drop_down.svg
new file mode 100644
index 0000000..6b131e1
--- /dev/null
+++ b/assets/icons/arrow_drop_down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/brightness_3.svg b/assets/icons/brightness_3.svg
new file mode 100644
index 0000000..a32b95f
--- /dev/null
+++ b/assets/icons/brightness_3.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/build.svg b/assets/icons/build.svg
new file mode 100644
index 0000000..624e8ff
--- /dev/null
+++ b/assets/icons/build.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/check.svg b/assets/icons/check.svg
new file mode 100644
index 0000000..d234388
--- /dev/null
+++ b/assets/icons/check.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/check_box.svg b/assets/icons/check_box.svg
new file mode 100644
index 0000000..4860b0f
--- /dev/null
+++ b/assets/icons/check_box.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/done_all.svg b/assets/icons/done_all.svg
new file mode 100644
index 0000000..074c14f
--- /dev/null
+++ b/assets/icons/done_all.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/edit.svg b/assets/icons/edit.svg
new file mode 100644
index 0000000..9c51aed
--- /dev/null
+++ b/assets/icons/edit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/event_note.svg b/assets/icons/event_note.svg
new file mode 100644
index 0000000..3cc5756
--- /dev/null
+++ b/assets/icons/event_note.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/first_page.svg b/assets/icons/first_page.svg
new file mode 100644
index 0000000..68d9f8b
--- /dev/null
+++ b/assets/icons/first_page.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/format_list_bulleted.svg b/assets/icons/format_list_bulleted.svg
new file mode 100644
index 0000000..ee892c5
--- /dev/null
+++ b/assets/icons/format_list_bulleted.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/info.svg b/assets/icons/info.svg
new file mode 100644
index 0000000..ef7e440
--- /dev/null
+++ b/assets/icons/info.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/landscape.svg b/assets/icons/landscape.svg
new file mode 100644
index 0000000..6ffb6ce
--- /dev/null
+++ b/assets/icons/landscape.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/last_page.svg b/assets/icons/last_page.svg
new file mode 100644
index 0000000..a398b5d
--- /dev/null
+++ b/assets/icons/last_page.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/list.svg b/assets/icons/list.svg
new file mode 100644
index 0000000..22a518a
--- /dev/null
+++ b/assets/icons/list.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/menu.svg b/assets/icons/menu.svg
new file mode 100644
index 0000000..30f9b60
--- /dev/null
+++ b/assets/icons/menu.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/navigate_next.svg b/assets/icons/navigate_next.svg
new file mode 100644
index 0000000..bba18c0
--- /dev/null
+++ b/assets/icons/navigate_next.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/office.svg b/assets/icons/office.svg
new file mode 100644
index 0000000..cc885c0
--- /dev/null
+++ b/assets/icons/office.svg
@@ -0,0 +1,69 @@
+
\ No newline at end of file
diff --git a/assets/icons/school.svg b/assets/icons/school.svg
new file mode 100644
index 0000000..b165dec
--- /dev/null
+++ b/assets/icons/school.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/settings.svg b/assets/icons/settings.svg
new file mode 100644
index 0000000..b0f0e4f
--- /dev/null
+++ b/assets/icons/settings.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/wb_sunny.svg b/assets/icons/wb_sunny.svg
new file mode 100644
index 0000000..a11957c
--- /dev/null
+++ b/assets/icons/wb_sunny.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/work.svg b/assets/icons/work.svg
new file mode 100644
index 0000000..8cd7eb6
--- /dev/null
+++ b/assets/icons/work.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/default_user.png b/assets/images/default_user.png
new file mode 100644
index 0000000..7f0f057
Binary files /dev/null and b/assets/images/default_user.png differ
diff --git a/assets/ms_icon.png b/assets/ms_icon.png
deleted file mode 100644
index 9e5e2bc..0000000
Binary files a/assets/ms_icon.png and /dev/null differ
diff --git a/ios/.gitignore b/ios/.gitignore
new file mode 100644
index 0000000..0f1df0f
--- /dev/null
+++ b/ios/.gitignore
@@ -0,0 +1,32 @@
+*.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/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
index 6b4c0f7..58e65f9 100644
--- a/ios/Flutter/AppFrameworkInfo.plist
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -1,26 +1,26 @@
-
-
-
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleExecutable
- App
- CFBundleIdentifier
- io.flutter.flutter.app
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- App
- CFBundlePackageType
- FMWK
- CFBundleShortVersionString
- 1.0
- CFBundleSignature
- ????
- CFBundleVersion
- 1.0
- MinimumOSVersion
- 8.0
-
-
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ MinimumOSVersion
+ 8.0
+
+
diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig
index 592ceee..0b2d479 100644
--- a/ios/Flutter/Debug.xcconfig
+++ b/ios/Flutter/Debug.xcconfig
@@ -1 +1 @@
-#include "Generated.xcconfig"
+#include "Generated.xcconfig"
diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig
index 592ceee..0b2d479 100644
--- a/ios/Flutter/Release.xcconfig
+++ b/ios/Flutter/Release.xcconfig
@@ -1 +1 @@
-#include "Generated.xcconfig"
+#include "Generated.xcconfig"
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index a927c80..4612478 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -1,519 +1,518 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 46;
- objects = {
-
-/* Begin PBXBuildFile section */
- 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
- 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
- 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
- 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
- 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
- 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
- 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 */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
- 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
- );
- name = "Embed Frameworks";
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
- 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
- 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
- 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
- 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
- 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
- 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
- 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
- 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
- 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
- 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
- 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
- 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 97C146EB1CF9000F007C117D /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
- 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 9740EEB11CF90186004384FC /* Flutter */ = {
- isa = PBXGroup;
- children = (
- 3B80C3931E831B6300D905FE /* App.framework */,
- 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
- 9740EEBA1CF902C7004384FC /* Flutter.framework */,
- 9740EEB21CF90195004384FC /* Debug.xcconfig */,
- 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
- 9740EEB31CF90195004384FC /* Generated.xcconfig */,
- );
- name = Flutter;
- sourceTree = "";
- };
- 97C146E51CF9000F007C117D = {
- isa = PBXGroup;
- children = (
- 9740EEB11CF90186004384FC /* Flutter */,
- 97C146F01CF9000F007C117D /* Runner */,
- 97C146EF1CF9000F007C117D /* Products */,
- );
- sourceTree = "";
- };
- 97C146EF1CF9000F007C117D /* Products */ = {
- isa = PBXGroup;
- children = (
- 97C146EE1CF9000F007C117D /* Runner.app */,
- );
- name = Products;
- sourceTree = "";
- };
- 97C146F01CF9000F007C117D /* Runner */ = {
- isa = PBXGroup;
- children = (
- 97C146FA1CF9000F007C117D /* Main.storyboard */,
- 97C146FD1CF9000F007C117D /* Assets.xcassets */,
- 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
- 97C147021CF9000F007C117D /* Info.plist */,
- 97C146F11CF9000F007C117D /* Supporting Files */,
- 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
- 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
- 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
- 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
- );
- path = Runner;
- sourceTree = "";
- };
- 97C146F11CF9000F007C117D /* Supporting Files */ = {
- isa = PBXGroup;
- children = (
- );
- name = "Supporting Files";
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 97C146ED1CF9000F007C117D /* Runner */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
- buildPhases = (
- 9740EEB61CF901F6004384FC /* Run Script */,
- 97C146EA1CF9000F007C117D /* Sources */,
- 97C146EB1CF9000F007C117D /* Frameworks */,
- 97C146EC1CF9000F007C117D /* Resources */,
- 9705A1C41CF9048500538489 /* Embed Frameworks */,
- 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = Runner;
- productName = Runner;
- productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 97C146E61CF9000F007C117D /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastUpgradeCheck = 1020;
- ORGANIZATIONNAME = "The Chromium Authors";
- TargetAttributes = {
- 97C146ED1CF9000F007C117D = {
- CreatedOnToolsVersion = 7.3.1;
- LastSwiftMigration = 0910;
- };
- };
- };
- buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
- compatibilityVersion = "Xcode 3.2";
- developmentRegion = en;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = 97C146E51CF9000F007C117D;
- productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 97C146ED1CF9000F007C117D /* Runner */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 97C146EC1CF9000F007C117D /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
- 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
- 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
- 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
- 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "Thin Binary";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
- };
- 9740EEB61CF901F6004384FC /* Run Script */ = {
- isa = PBXShellScriptBuildPhase;
- 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 */
- 97C146EA1CF9000F007C117D /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
- 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXVariantGroup section */
- 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 97C146FB1CF9000F007C117D /* Base */,
- );
- name = Main.storyboard;
- sourceTree = "";
- };
- 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 97C147001CF9000F007C117D /* Base */,
- );
- name = LaunchScreen.storyboard;
- sourceTree = "";
- };
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
- 249021D3217E4FDB00AE95B9 /* Profile */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 8.0;
- MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- };
- name = Profile;
- };
- 249021D4217E4FDB00AE95B9 /* Profile */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ENABLE_MODULES = YES;
- CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- ENABLE_BITCODE = NO;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)/Flutter",
- );
- INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)/Flutter",
- );
- PRODUCT_BUNDLE_IDENTIFIER = fr.litarvan.epilyon;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_VERSION = 4.0;
- VERSIONING_SYSTEM = "apple-generic";
- };
- name = Profile;
- };
- 97C147031CF9000F007C117D /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 8.0;
- MTL_ENABLE_DEBUG_INFO = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Debug;
- };
- 97C147041CF9000F007C117D /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 8.0;
- MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- 97C147061CF9000F007C117D /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ENABLE_MODULES = YES;
- CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- ENABLE_BITCODE = NO;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)/Flutter",
- );
- INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)/Flutter",
- );
- PRODUCT_BUNDLE_IDENTIFIER = fr.litarvan.epilyon;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 4.0;
- VERSIONING_SYSTEM = "apple-generic";
- };
- name = Debug;
- };
- 97C147071CF9000F007C117D /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ENABLE_MODULES = YES;
- CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- ENABLE_BITCODE = NO;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)/Flutter",
- );
- INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)/Flutter",
- );
- PRODUCT_BUNDLE_IDENTIFIER = fr.litarvan.epilyon;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_VERSION = 4.0;
- VERSIONING_SYSTEM = "apple-generic";
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 97C147031CF9000F007C117D /* Debug */,
- 97C147041CF9000F007C117D /* Release */,
- 249021D3217E4FDB00AE95B9 /* Profile */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 97C147061CF9000F007C117D /* Debug */,
- 97C147071CF9000F007C117D /* Release */,
- 249021D4217E4FDB00AE95B9 /* Profile */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
-
- };
- rootObject = 97C146E61CF9000F007C117D /* Project object */;
-}
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 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 */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
+ 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B80C3931E831B6300D905FE /* App.framework */,
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEBA1CF902C7004384FC /* Flutter.framework */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 97C146F11CF9000F007C117D /* Supporting Files */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+ 97C146F11CF9000F007C117D /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 1020;
+ ORGANIZATIONNAME = "The Chromium Authors";
+ TargetAttributes = {
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 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 */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ 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 */
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.litarvan.epilyon;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.litarvan.epilyon;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.litarvan.epilyon;
+ 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 */
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ 249021D3217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ 249021D4217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index 1d526a1..59c6d39 100644
--- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -1,7 +1,7 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index a28140c..be0b92e 100644
--- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,91 +1,91 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata
index 1d526a1..59c6d39 100644
--- a/ios/Runner.xcworkspace/contents.xcworkspacedata
+++ b/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -1,7 +1,7 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index 70693e4..3763683 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -1,13 +1,13 @@
-import UIKit
-import Flutter
-
-@UIApplicationMain
-@objc class AppDelegate: FlutterAppDelegate {
- override func application(
- _ application: UIApplication,
- didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
- ) -> Bool {
- GeneratedPluginRegistrant.register(with: self)
- return super.application(application, didFinishLaunchingWithOptions: launchOptions)
- }
-}
+import UIKit
+import Flutter
+
+@UIApplicationMain
+@objc class AppDelegate: FlutterAppDelegate {
+ override func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+ GeneratedPluginRegistrant.register(with: self)
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+}
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
index d36b1fa..1950fd8 100644
--- a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1,122 +1,122 @@
-{
- "images" : [
- {
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "Icon-App-20x20@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "Icon-App-20x20@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "Icon-App-40x40@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "Icon-App-40x40@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "Icon-App-60x60@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "Icon-App-60x60@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "Icon-App-20x20@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "Icon-App-20x20@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "Icon-App-29x29@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "Icon-App-29x29@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "Icon-App-40x40@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "Icon-App-40x40@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "Icon-App-76x76@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "Icon-App-76x76@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "83.5x83.5",
- "idiom" : "ipad",
- "filename" : "Icon-App-83.5x83.5@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "1024x1024",
- "idiom" : "ios-marketing",
- "filename" : "Icon-App-1024x1024@1x.png",
- "scale" : "1x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "Icon-App-1024x1024@1x.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
index 0bedcf2..d08a4de 100644
--- a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
+++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -1,23 +1,23 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "filename" : "LaunchImage.png",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "filename" : "LaunchImage@2x.png",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "filename" : "LaunchImage@3x.png",
- "scale" : "3x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
index 89c2725..65a94b5 100644
--- a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
+++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -1,5 +1,5 @@
-# Launch Screen Assets
-
-You can customize the launch screen with your own desired assets by replacing the image files in this directory.
-
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard
index f2e259c..497371e 100644
--- a/ios/Runner/Base.lproj/LaunchScreen.storyboard
+++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -1,37 +1,37 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard
index f3c2851..bbb83ca 100644
--- a/ios/Runner/Base.lproj/Main.storyboard
+++ b/ios/Runner/Base.lproj/Main.storyboard
@@ -1,26 +1,26 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 6cbc0ab..d8c97fa 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -1,47 +1,45 @@
-
-
-
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- epilyon
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- $(FLUTTER_BUILD_NAME)
- CFBundleSignature
- ????
- CFBundleVersion
- $(FLUTTER_BUILD_NUMBER)
- LSRequiresIPhoneOS
-
- UILaunchStoryboardName
- LaunchScreen
- UIMainStoryboardFile
- Main
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UIViewControllerBasedStatusBarAppearance
-
- io.flutter.embedded_views_previewyes
-
-
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ epilyon
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIViewControllerBasedStatusBarAppearance
+
+
+
diff --git a/lib/api.dart b/lib/api.dart
index 9358431..217d274 100644
--- a/lib/api.dart
+++ b/lib/api.dart
@@ -1,3 +1,48 @@
-// The point of this file is to be edited in local
-// This is the simplest way to do it, just don't push your changes of this file to git
-const API_URL = "https://INSERT_API_URL";
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'dart:convert';
+
+// TODO: Handle down API and down CRI
+
+dynamic parseResponse(String body)
+{
+ var json;
+
+ try {
+ json = jsonDecode(body);
+
+ if (json['success'] == null) {
+ throw 'No success field';
+ }
+ } catch (e, trace) {
+ print('JSON decoding error : ' + e.toString());
+ print(trace);
+
+ throw UnreachableAPIException();
+ }
+
+ if (json['success'] != true) {
+ throw json['error'];
+ }
+
+ return json;
+}
+
+class UnreachableAPIException implements Exception
+{
+}
\ No newline at end of file
diff --git a/lib/api_url.dart b/lib/api_url.dart
new file mode 100644
index 0000000..c9cb5c4
--- /dev/null
+++ b/lib/api_url.dart
@@ -0,0 +1,3 @@
+// The point of this file is to be edited in local
+// This is the simplest way to do it, just don't push your changes of this file to git
+const API_URL = 'YOUR API URL';
\ No newline at end of file
diff --git a/lib/auth.dart b/lib/auth.dart
index 07187b4..65f9bf4 100644
--- a/lib/auth.dart
+++ b/lib/auth.dart
@@ -1,92 +1,135 @@
-import 'dart:convert';
-
-import 'package:http/http.dart' as http;
-import 'package:shared_preferences/shared_preferences.dart';
-
-import 'package:epilyon/api.dart';
-
-var _token = "";
-User _user;
-
-class User
-{
- int id;
- String name;
- String email;
- String promo;
- String region;
-
- User(this.id, this.name, this.email, this.promo, this.region);
-}
-
-Future refresh() async
-{
- final prefs = await SharedPreferences.getInstance();
- var token = prefs.getString("token");
-
- if (token == null) {
- return false;
- }
-
- var result = await http.post(API_URL + '/auth/refresh', headers: {
- "Authorization": "Bearer " + token
- });
-
- var json = jsonDecode(result.body);
- if (json["token"] != null) {
- _token = json["token"];
- prefs.setString("token", _token);
-
- await login();
-
- return true;
- }
-
- return false;
-}
-
-Future createSession() async
-{
- var result = await http.post(API_URL + '/auth/start'); // TODO: Handle possible error (generic function?)
- _token = jsonDecode(result.body)["token"];
-}
-
-Future login() async
-{
- var result = await http.post(API_URL + "/auth/end", headers: { // TODO: Handle errors!
- "Authorization": "Bearer " + getToken()
- });
-
- var content = jsonDecode(result.body);
- _user = User(content["id"], content["name"], content["email"], content["promo"], content["region"]); // TODO: ...
-
- if (content["id"] != null) {
- final prefs = await SharedPreferences.getInstance();
- prefs.setString("token", _token);
- }
-}
-
-Future logout() async
-{
- var result = await http.post(API_URL + "/auth/logout", headers: {
- "Authorization": "Bearer " + getToken()
- });
-
- bool success = jsonDecode(result.body)["success"] == true;
-
- if (success) {
- _token = "";
- }
-
- return success;
-}
-
-String getToken()
-{
- return _token;
-}
-
-User getUser()
-{
- return _user;
-}
\ No newline at end of file
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:http/http.dart' as http;
+import 'package:shared_preferences/shared_preferences.dart';
+
+import 'package:epilyon/api_url.dart';
+import 'package:epilyon/api.dart';
+
+String _token = "";
+User _user;
+
+class User
+{
+ String username;
+ String firstName;
+ String lastName;
+ String email;
+ String promo;
+ String avatar;
+
+ User(this.username, this.firstName, this.lastName, this.email, this.promo, this.avatar);
+}
+
+Future canRefresh() async
+{
+ final prefs = await SharedPreferences.getInstance();
+ return prefs.getString('token') != null;
+}
+
+Future refresh() async
+{
+ final prefs = await SharedPreferences.getInstance();
+ var token = prefs.getString('token');
+ if (token == null) {
+ return false;
+ }
+
+ var result = await http.post(API_URL + '/auth/refresh', headers: {
+ 'Token': token
+ });
+
+ var json;
+ try {
+ json = parseResponse(result.body);
+ } catch (e) {
+ prefs.remove('token');
+ throw e;
+ }
+
+ _token = json["token"];
+ await setUser(json["user"]);
+
+ return true;
+}
+
+Future createSession() async
+{
+ var result = await http.post(API_URL + '/auth/start');
+ _token = parseResponse(result.body)['token'];
+}
+
+Future login() async
+{
+ var result = await http.post(API_URL + '/auth/end', headers: {
+ 'Token': getToken()
+ });
+
+ await setUser(parseResponse(result.body)['user']);
+}
+
+Future cancelLogin() async
+{
+ _token = '';
+ _user = null;
+
+ final prefs = await SharedPreferences.getInstance();
+ prefs.remove('token');
+}
+
+Future setUser(dynamic user) async
+{
+ final prefs = await SharedPreferences.getInstance();
+ prefs.setString('token', _token);
+
+ _user = User(
+ user['username'],
+ user['first_name'],
+ user['last_name'],
+ user['email'],
+ user['promo'],
+ user['avatar']
+ );
+
+ print("Logged in as '" + _user.firstName + " " + _user.lastName + "'");
+}
+
+Future logout() async
+{
+ var result = await http.post(API_URL + '/auth/logout', headers: {
+ 'Token': getToken()
+ });
+
+ parseResponse(result.body);
+
+ _token = '';
+ _user = null;
+
+ final prefs = await SharedPreferences.getInstance();
+ prefs.remove('token');
+}
+
+String getToken()
+{
+ return _token;
+}
+
+User getUser()
+{
+ return _user;
+}
diff --git a/lib/base.dart b/lib/base.dart
new file mode 100644
index 0000000..71d2326
--- /dev/null
+++ b/lib/base.dart
@@ -0,0 +1,414 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+import 'package:epilyon/auth.dart';
+import 'package:epilyon/pages/about.dart';
+import 'package:epilyon/pages/login.dart';
+import 'package:epilyon/pages/logout.dart';
+import 'package:epilyon/pages/qcm/last_qcm.dart';
+
+class Page {
+ String title;
+ String tabTitle;
+ String icon;
+ Widget page;
+ List tabs;
+ int tabIndex;
+ PageDisplay display;
+
+ Page({
+ @required this.title,
+ this.tabTitle,
+ @required this.icon,
+ this.page,
+ this.tabs = const [],
+ this.tabIndex = 0,
+ this.display = PageDisplay.WHEN_LOGGED_IN
+ });
+}
+
+enum PageDisplay {
+ WHEN_LOGGED_IN,
+ WHEN_LOGGED_OUT,
+ ALWAYS
+}
+
+// TODO: Preload assets ? (Check performance on a release build)
+
+void pushBase(BuildContext context)
+{
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(builder: (context) => BasePage())
+ );
+}
+
+class BasePage extends StatefulWidget {
+ BasePage({ Key key }) : super(key: key);
+
+ @override
+ _BasePageState createState() => _BasePageState();
+}
+
+class _BasePageState extends State {
+ final List pages = [
+ Page(
+ title: 'Q.C.M.s',
+ icon: 'assets/icons/check_box.svg',
+ tabIndex: 1, // TODO: Change this depending on the day/time
+ tabs: [
+ Page(
+ title: 'Prochain Q.C.M.',
+ tabTitle: 'Prochain',
+ icon: 'assets/icons/edit.svg',
+ ),
+ Page(
+ title: 'Résultats du Q.C.M.',
+ tabTitle: 'Résultats',
+ icon: 'assets/icons/done_all.svg',
+ page: LastQCMPage()
+ ),
+ Page(
+ title: 'Historique des Q.C.M.s',
+ icon: 'assets/icons/list.svg',
+ tabTitle: 'Historique',
+ )
+ ]
+ ),
+ Page(
+ title: 'MiMos',
+ icon: 'assets/icons/work.svg',
+ //page:
+ ),
+ Page(
+ title: 'Gérer',
+ icon: 'assets/icons/build.svg',
+ //page:
+ ),
+ Page(
+ title: 'Paramètres',
+ icon: 'assets/icons/settings.svg',
+ //page:
+ ),
+ Page(
+ title: 'Se déconnecter',
+ icon: 'assets/icons/first_page.svg',
+ page: LogoutPage()
+ ),
+ Page(
+ title: 'Se connecter',
+ icon: 'assets/icons/last_page.svg',
+ page: LoginPage(),
+ display: PageDisplay.WHEN_LOGGED_OUT
+ ),
+ Page(
+ title: 'À Propos',
+ icon: 'assets/icons/info.svg',
+ page: AboutPage(),
+ display: PageDisplay.ALWAYS
+ ),
+ ];
+
+ // TODO: Page switching animation ?
+ Page selectedPage;
+
+ @override
+ void initState() {
+ super.initState();
+ selectedPage = getUser() == null ? pages[5] : pages[0];
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ Color primary = Theme.of(context).primaryColor;
+ MediaQueryData media = MediaQuery.of(context);
+ double barHeight = 54.0;
+
+ Widget content = selectedPage.tabs.length > 0
+ ? selectedPage.tabs[selectedPage.tabIndex].page
+ : selectedPage.page;
+
+ return Scaffold(
+ appBar: buildAppBar(context, barHeight),
+ drawer: buildDrawer(context),
+ bottomNavigationBar: selectedPage.tabs.length > 0 ? BottomNavigationBar(
+ currentIndex: selectedPage.tabIndex,
+ elevation: 20.0,
+ onTap: (tab) => setState(() {
+ if (selectedPage.tabs[tab].page != null) {
+ selectedPage.tabIndex = tab;
+ }
+ }),
+ items: selectedPage.tabs.map((page) {
+ bool selected = content == page.page;
+
+ return BottomNavigationBarItem(
+ icon: SvgPicture.asset(
+ page.icon,
+ width: 24,
+ color: selected ? primary : Color(0xFF999999),
+ ), // TODO: Better way ?
+ title: Text(page.tabTitle != null ? page.tabTitle : page.title)
+ );
+ }).toList(),
+ ) : null,
+ body: SingleChildScrollView(
+ child: Container(
+ child: content,
+ height: media.size.height - media.padding.top - barHeight
+ - (selectedPage.tabs.length > 0 ? kBottomNavigationBarHeight : 0),
+ )
+ )
+ );
+ }
+
+ Widget buildAppBar(BuildContext context, double height)
+ {
+ return PreferredSize(
+ child: Container(
+ decoration: BoxDecoration(boxShadow: [
+ BoxShadow(
+ color: Color.fromRGBO(6, 6, 6, 0.35),
+ offset: Offset(0, 2.0),
+ blurRadius: 5.0,
+ )
+ ]),
+ child: AppBar(
+ elevation: 0.0,
+ title: Text(
+ selectedPage.tabs.length > 0
+ ? selectedPage.tabs[selectedPage.tabIndex].title
+ : selectedPage.title
+ ),
+ titleSpacing: 3.0,
+ leading: Builder(
+ builder: (BuildContext context) {
+ return IconButton(
+ icon: SvgPicture.asset(
+ 'assets/icons/menu.svg',
+ width: 26,
+ height: 26,
+ ),
+ onPressed: () { Scaffold.of(context).openDrawer(); },
+ tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
+ );
+ }
+ ),
+ ),
+ ),
+ preferredSize: Size.fromHeight(height),
+ );
+ }
+
+ Widget buildDrawer(BuildContext context)
+ {
+ Color primary = Theme.of(context).primaryColor;
+ MediaQueryData media = MediaQuery.of(context);
+
+ User user = getUser();
+
+ return Theme(
+ data: Theme.of(context).copyWith(
+ canvasColor: primary,
+ textTheme: TextTheme(
+ body2: TextStyle(color: Colors.white, fontFamily: 'Lato2', fontSize: 18, fontWeight: FontWeight.w600)
+ )
+ ),
+ child: Drawer(
+ child: ListView(
+ padding: EdgeInsets.zero,
+ children: [
+ Theme(
+ data: Theme.of(context).copyWith(
+ textTheme: TextTheme(
+ body1: TextStyle(color: Colors.black, fontFamily: 'Lato')
+ )
+ ),
+ child: Container(
+ padding: EdgeInsets.only(left: 12.5, top: 12.5 + media.padding.top),
+ height: 150.0,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ Container(
+ width: 60,
+ height: 60,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ image: DecorationImage(
+ image: user != null
+ ? NetworkImage(user.avatar)
+ : AssetImage('assets/images/default_user.png'),
+ fit: BoxFit.cover,
+ alignment: Alignment.topCenter
+ )
+ )
+ ),
+ Padding(
+ padding: const EdgeInsets.only(left: 12.5),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(left: 0.75), // To compensate the use of italic
+ child: Row(
+ children: [
+ Text(
+ user != null ? user.firstName : 'Utilisateur',
+ style: TextStyle(
+ fontSize: 18.0,
+ fontStyle: FontStyle.italic,
+ fontWeight: FontWeight.normal,
+ color: Colors.black
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(left: 5.0),
+ child: Container(
+ decoration: BoxDecoration(
+ color: Colors.black,
+ borderRadius: BorderRadius.all(Radius.circular(3.0))
+ ),
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(left: 5.0, right: 5.0, top: 3.0),
+ child: Text(
+ user == null ? '???' : (
+ user.promo == '2024' ? 'SUP' : 'SPÉ' // TODO: Smart way
+ ),
+ style: TextStyle(
+ height: 1,
+ fontFamily: 'Lato3',
+ fontSize: 18.0,
+ fontWeight: FontWeight.w600,
+ color: Colors.white
+ )
+ ),
+ ),
+ ],
+ ),
+ ),
+ )
+ ],
+ ),
+ ),
+ Text(
+ user != null ? user.lastName : 'Inconnu',
+ style: TextStyle(
+ fontSize: 18.0,
+ fontFamily: 'Lato2',
+ fontWeight: FontWeight.w600,
+ color: Colors.black
+ ),
+ )
+ ],
+ ),
+ )
+ ],
+ ),
+ Padding(
+ padding: const EdgeInsets.only(top: 12.5, left: 2.5),
+ child: Text(
+ 'Lyon - ' + (user != null ? user.promo : '?'), // Temporary, groups will be there then
+ style: TextStyle(
+ color: Colors.black,
+ fontSize: 18,
+ fontFamily: 'Lato',
+ fontWeight: FontWeight.w700,
+ fontStyle: FontStyle.italic
+ ),
+ ),
+ )
+ ],
+ ),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ boxShadow: [
+ BoxShadow(
+ offset: Offset(1.0, 1.0),
+ blurRadius: 5.0,
+ color: Color.fromRGBO(28, 28, 28, 0.55),
+ )
+ ]
+ ),
+ ),
+ ),
+ Container(
+ child: Padding(
+ padding: const EdgeInsets.only(left: 15.0, top: 20.0),
+ child: Wrap(
+ runSpacing: 10.0,
+ children: pages.map((page) {
+ bool selected = page == selectedPage;
+
+ if (!(user == null && page.display == PageDisplay.WHEN_LOGGED_OUT ||
+ user != null && page.display == PageDisplay.WHEN_LOGGED_IN ||
+ page.display == PageDisplay.ALWAYS)) {
+ return null;
+ }
+
+ return Container(
+ decoration: BoxDecoration(
+ color: selected ? Colors.white : null,
+ borderRadius: BorderRadius.only(topLeft: Radius.circular(5), bottomLeft: Radius.circular(5)),
+ boxShadow: selected ? [
+ BoxShadow(
+ offset: Offset(-1, 0),
+ blurRadius: 5.0,
+ color: Color.fromRGBO(62, 62, 62, 0.45)
+ )
+ ] : []
+ ),
+ child: ListTile(
+ leading: SvgPicture.asset(page.icon, width: 24, color: selected ? primary : Colors.white),
+ title: Padding(
+ padding: const EdgeInsets.only(bottom: 1.0),
+ child: Text(page.title, style: TextStyle(color: selected ? primary : Colors.white)),
+ ),
+ trailing: SvgPicture.asset(
+ 'assets/icons/navigate_next.svg',
+ width: 30,
+ color: selected ? primary : Colors.white
+ ),
+ contentPadding: EdgeInsets.only(left: 20.0, right: 10.0),
+ onTap: () {
+ if (page.page != null || page.tabs.length > 0) {
+ setState(() {
+ selectedPage = page;
+ });
+ }
+
+ Navigator.pop(context);
+ },
+ ),
+ );
+ }).where((p) => p != null).toList()
+ ),
+ ),
+ )
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/data.dart b/lib/data.dart
new file mode 100644
index 0000000..65f6545
--- /dev/null
+++ b/lib/data.dart
@@ -0,0 +1,101 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'dart:convert';
+
+import 'package:intl/intl.dart';
+import 'package:http/http.dart' as http;
+
+import 'package:epilyon/api_url.dart';
+import 'package:epilyon/api.dart';
+import 'package:epilyon/auth.dart';
+
+class UserData
+{
+ List qcmHistory;
+
+ UserData({ this.qcmHistory });
+}
+
+// TODO: Save data
+
+UserData data;
+
+Future fetchData() async {
+ var result = await http.get(API_URL + '/data/get', headers: {
+ 'Token': getToken()
+ });
+
+ data = parseData(parseResponse(utf8.decode(result.bodyBytes))['data']);
+}
+
+// TODO: Refresh on start + refresh button
+Future forceRefresh() async {
+ var result = await http.post(API_URL + '/data/refresh', headers: {
+ 'Token': getToken()
+ });
+
+ parseResponse(result.body);
+}
+
+UserData parseData(dynamic data)
+{
+ DateFormat format = new DateFormat("yyyy-MM-dd");
+ List qcms = data['history'].map((qcm) {
+ List grades = qcm['grades'].map((grade) => QCMGrade(
+ grade['subject'],
+ grade['points']
+ .map((p) => p as double)
+ .toList()
+ .reduce((a, b) => a + b)
+ )).toList();
+
+ if (grades.length == 7) {
+ grades.insert(6, grades.removeAt(0));
+ grades.insert(6, grades.removeAt(0));
+ }
+
+ return QCM(
+ format.parse(qcm['date']),
+ qcm['average'],
+ grades
+ );
+ }).toList();
+
+ qcms.sort((a, b) => -a.date.compareTo(b.date));
+
+ return UserData(
+ qcmHistory: qcms
+ );
+}
+
+class QCM
+{
+ DateTime date;
+ double average;
+ List grades;
+
+ QCM(this.date, this.average, this.grades);
+}
+
+class QCMGrade
+{
+ String subject;
+ double grade;
+
+ QCMGrade(this.subject, this.grade);
+}
\ No newline at end of file
diff --git a/lib/main.dart b/lib/main.dart
index a34e05f..e37788a 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,21 +1,53 @@
-import 'package:flutter/material.dart';
-import 'package:epilyon/pages/login.dart';
-
-// TODO: Move every http call in a separated file, manage async and errors properly
-
-void main() => runApp(EpilyonApp());
-
-class EpilyonApp extends StatelessWidget
-{
- @override
- Widget build(BuildContext context)
- {
- return MaterialApp(
- title: 'Epilyon',
- theme: ThemeData(
- primaryColor: Colors.lightGreenAccent[700],
- ),
- home: LoginPage(title: 'Epilyon'), // TODO: Handle login and refresh
- );
- }
-}
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+import 'package:intl/date_symbol_data_local.dart';
+
+import 'package:epilyon/pages/refresh.dart';
+
+const VERSION = 'v0.1.0';
+
+void main()
+{
+ initializeDateFormatting('fr_FR');
+ runApp(MyApp());
+}
+
+class MyApp extends StatelessWidget
+{
+ @override
+ Widget build(BuildContext context)
+ {
+ return MaterialApp(
+ title: 'Epilyon',
+ theme: ThemeData(
+ // TODO: Custom theming
+ primaryColor: Color(0xFF027CFF), // 0xFF8643e6
+ canvasColor: Color(0xFFF5F7F9),
+ fontFamily: 'Roboto',
+ appBarTheme: AppBarTheme(
+ textTheme: TextTheme(
+ title: TextStyle(fontFamily: 'Lato2', fontSize: 19, fontWeight: FontWeight.w600)
+ ),
+ elevation: 0
+ )
+ ),
+ home: RefreshPage(),
+ );
+ }
+}
diff --git a/lib/pages/about.dart b/lib/pages/about.dart
new file mode 100644
index 0000000..2a87853
--- /dev/null
+++ b/lib/pages/about.dart
@@ -0,0 +1,94 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+import 'package:epilyon/main.dart';
+import 'package:epilyon/widgets/button.dart';
+import 'package:epilyon/widgets/card.dart';
+
+class AboutPage extends StatefulWidget
+{
+ AboutPage({ Key key }) : super(key: key);
+
+ @override
+ _AboutPageState createState() => _AboutPageState();
+}
+
+class _AboutPageState extends State
+{
+ @override
+ Widget build(BuildContext context)
+ {
+ return Center(
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(top: 50.0),
+ child: Text('Epilyon', style: TextStyle(fontSize: 52, fontWeight: FontWeight.w500),),
+ ),
+ Text(VERSION, style: TextStyle(fontFamily: 'Lato2', fontSize: 22),),
+ Padding(
+ padding: const EdgeInsets.only(top: 10),
+ child: Text("Copyright (c) 2019-2020 Adrien 'Litarvan' Navratil", style: TextStyle(fontFamily: 'Lato', fontSize: 14),),
+ ),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 100.0, vertical: 30.0),
+ child: EpiButton(
+ onPressed: () => _launchURL('https://github.com/Epilyon/epilyon/raw/master/LICENSE'),
+ text: 'License',
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.symmetric(vertical: 10.0),
+ child: EpiCard(
+ title: 'Remerciements',
+ child: Padding(
+ padding: const EdgeInsets.only(left: 20.0, right: 20.0, bottom: 15.0),
+ child: Text(
+ "Mathis P., Louis P. et Ugo M.\n"
+ "Valentin C.\n"
+ "Martin S.\n"
+ "Matthieu (utybo)\n"
+ "Yann Michaux\n"
+ "Théo (Thelox), Thomas (Uxon)\n"
+ "Shika\n"
+ "Lamia, Marjolaine, et Patricia",
+ style: TextStyle(
+ fontSize: 18,
+ fontStyle: FontStyle.italic,
+ height: 1.5
+ ),
+ ),
+ ),
+ ),
+ )
+ ],
+ ),
+ );
+ }
+
+ _launchURL(url) async
+ {
+ if (await canLaunch(url)) {
+ await launch(url);
+ } else {
+ throw 'Could not launch $url';
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/pages/home.dart b/lib/pages/home.dart
deleted file mode 100644
index 0f1baed..0000000
--- a/lib/pages/home.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:epilyon/widgets/layout/drawer.dart';
-import 'package:epilyon/auth.dart';
-
-class HomePage extends StatefulWidget
-{
- HomePage({ Key key, this.title }) : super(key: key);
-
- final String title;
-
- @override
- _HomePageState createState() => _HomePageState();
-}
-
-class _HomePageState extends State
-{
- @override
- Widget build(BuildContext context)
- {
- var user = getUser();
-
- return Scaffold(
- appBar: AppBar(
- title: Text(widget.title),
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text("Bienvenue " + user.name + " (" + user.region + " " + user.promo + ")")
- ],
- ),
- ),
- drawer: EpilyonDrawer(),
- );
- }
-}
\ No newline at end of file
diff --git a/lib/pages/login.dart b/lib/pages/login.dart
index 5bf70b2..f01d66c 100644
--- a/lib/pages/login.dart
+++ b/lib/pages/login.dart
@@ -1,127 +1,110 @@
-import 'package:epilyon/pages/home.dart';
-import 'package:epilyon/state.dart';
-import 'package:flutter/material.dart';
-
-import 'package:epilyon/widgets/loading_dialog.dart';
-import 'package:epilyon/auth.dart';
-import 'package:epilyon/pages/ms_login.dart';
-import 'package:epilyon/widgets/microsoft_button.dart';
-
-class LoginPage extends StatefulWidget
-{
- // TODO: Instead of passing title in constructor, hard code it
- LoginPage({ Key key, @required this.title }) : super(key: key);
-
- final String title;
-
- @override
- _LoginPageState createState() => _LoginPageState();
-}
-
-class _LoginPageState extends State
-{
- BuildContext _dialogContext;
- bool _refreshing;
-
- @override
- void initState()
- {
- super.initState();
-
- _refreshing = true;
-
- refresh().then((success) {
- if (success) {
- fetchState().then((_) {
- Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => HomePage(title: "Accueil"))); // TODO: Generify?
- }); // TODO: Handle error
- } else {
- print("Refresh failed");
-
- setState(() {
- _refreshing = false;
- });
- }
- }).catchError((e) {
- print("Error while doing refresh");
- print(e);
-
- setState(() {
- _refreshing = false;
- });
- });
- }
-
- void _onConnectPress(BuildContext context)
- {
- showDialog(
- context: context,
- barrierDismissible: false,
- builder: (BuildContext context) {
- _dialogContext = context;
-
- return LoadingDialog(
- title: Text("Chargement"),
- content: Text("Création de la session..."),
- );
- }
- ).whenComplete(() {
- _dialogContext = null;
- });
-
- createSession().then((_) {
- if (_dialogContext == null) {
- return;
- }
-
- Navigator.pop(_dialogContext);
- Navigator.push(context, MaterialPageRoute(builder: (context) => MSLoginPage(title: "Connexion")));
- }).catchError((e) {
- if (_dialogContext == null) {
- return;
- }
-
- Navigator.pop(_dialogContext);
- showDialog(
- context: context,
- builder: (BuildContext context) => AlertDialog(
- title: Text("Erreur"),
- content: Text("Impossible de se connecter au serveur : " + e.toString()),
- actions: [
- FlatButton(
- child: Text("OK :("),
- onPressed: () {
- Navigator.of(context).pop();
- },
- )
- ],
- )
- );
- });
- }
-
- @override
- Widget build(BuildContext context)
- {
- return Scaffold(
- appBar: AppBar(
- title: Text(widget.title),
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text("Bienvenue", style: TextStyle(fontSize: 36, fontWeight: FontWeight.w500),),
- _refreshing ? Text("Chargement...", style: TextStyle(fontStyle: FontStyle.italic)) : Padding(
- padding: const EdgeInsets.all(25.0),
- child: MicrosoftButton(
- text: "Se connecter avec Microsoft", // TODO: Lang
- onPressed: () => _onConnectPress(context),
- ),
- )
- ],
- ),
- ),
- );
- }
-}
\ No newline at end of file
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+import 'package:epilyon/auth.dart';
+import 'package:epilyon/widgets/dialogs.dart';
+import 'package:epilyon/widgets/office_button.dart';
+import 'package:epilyon/pages/ms_login.dart';
+
+// TODO: Rework this with a modern look
+
+class LoginPage extends StatefulWidget
+{
+ LoginPage({ Key key }) : super(key: key);
+
+ @override
+ _LoginPageState createState() => _LoginPageState();
+}
+
+class _LoginPageState extends State
+{
+ BuildContext _dialogContext;
+
+ void _onConnectPress(BuildContext context)
+ {
+ showLoadingDialog(
+ context,
+ title: 'Chargement',
+ content: 'Création de la session...',
+ onContextUpdate: (ctx) => _dialogContext = ctx
+ );
+
+ createSession().then((_) {
+ if (_dialogContext == null) {
+ return;
+ }
+
+ Navigator.pop(_dialogContext);
+ Navigator.push(
+ context,
+ MaterialPageRoute(builder: (context) => MSLoginPage(title: "Connexion"))
+ );
+ }).catchError((e, trace) {
+ if (_dialogContext == null) {
+ return;
+ }
+
+ print('Error during session creation : ' + e.toString());
+ print(trace);
+
+ Navigator.pop(_dialogContext);
+ showErrorDialog(
+ context,
+ title: 'Erreur',
+ content: 'Impossible de se connecter au serveur : ' + e.toString()
+ );
+ });
+ }
+
+ @override
+ Widget build(BuildContext context)
+ {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.only(top: 15.0, bottom: 30.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ Text("Bienvenue", style: TextStyle(fontSize: 50, fontWeight: FontWeight.w500),),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 20.0),
+ child: Text(
+ "Bienvenue sur Epilyon, une application déstinée aux étudiants de l’EPITA "
+ "de Lyon visant à rendre leur quotidien un peu moins chiant et à les forcer "
+ "à travailler un peu plus.\n\n"
+ "Un compte Office 365 en @epita.fr est requis pour utiliser l’application "
+ "(logique), je ne ferai pas de bétise avec, promis.",
+ textAlign: TextAlign.center,
+ style: TextStyle(fontSize: 18)
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 35.0),
+ child: OfficeButton(
+ onPressed: () => _onConnectPress(context),
+ text: "Se connecter via Office 365",
+ ),
+ )
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/pages/logout.dart b/lib/pages/logout.dart
new file mode 100644
index 0000000..97a87b4
--- /dev/null
+++ b/lib/pages/logout.dart
@@ -0,0 +1,74 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+import 'package:flutter/scheduler.dart';
+
+import 'package:epilyon/auth.dart';
+import 'package:epilyon/base.dart';
+import 'package:epilyon/widgets/dialogs.dart';
+
+class LogoutPage extends StatefulWidget
+{
+ LogoutPage({Key key}) : super(key: key);
+
+ @override
+ _LogoutPageState createState() => _LogoutPageState();
+}
+
+class _LogoutPageState extends State
+{
+ BuildContext _dialogContext;
+
+ @override
+ void initState()
+ {
+ super.initState();
+
+ SchedulerBinding.instance.addPostFrameCallback((_) async {
+ showLoadingDialog(
+ context,
+ title: 'Déconnexion',
+ content: 'Déconnexion en cours...',
+ onContextUpdate: (ctx) => _dialogContext = ctx
+ );
+
+ logout().catchError((e, trace) {
+ print('Error while doing logout : ' + e.toString());
+ print(trace);
+
+ showErrorDialog(
+ context,
+ title: 'Erreur',
+ content: "Erreur lors de la déconnexion : " + e.toString()
+ );
+ }).whenComplete(() {
+ if (_dialogContext == null) {
+ Navigator.pop(_dialogContext);
+ }
+
+ pushBase(context);
+ });
+ });
+ }
+
+ @override
+ Widget build(BuildContext context)
+ {
+ return Container();
+ }
+}
diff --git a/lib/pages/ms_login.dart b/lib/pages/ms_login.dart
index e2d3a6d..f40534b 100644
--- a/lib/pages/ms_login.dart
+++ b/lib/pages/ms_login.dart
@@ -1,11 +1,28 @@
-import 'package:epilyon/state.dart';
-import 'package:epilyon/widgets/loading_dialog.dart';
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
+import 'package:epilyon/base.dart';
+import 'package:epilyon/widgets/dialogs.dart';
+import 'package:epilyon/data.dart';
import 'package:epilyon/auth.dart';
-import 'package:epilyon/pages/home.dart';
-import 'package:epilyon/api.dart';
+import 'package:epilyon/api_url.dart';
class MSLoginPage extends StatefulWidget
{
@@ -23,9 +40,8 @@ class _MSLoginPageState extends State
Future _onWebViewCreated(WebViewController controller) async
{
- // TODO: Logging
controller.loadUrl(API_URL + "/auth/login", headers: {
- "Authorization": "Bearer " + getToken()
+ "Token": getToken()
});
}
@@ -35,51 +51,41 @@ class _MSLoginPageState extends State
return;
}
- showDialog(
- context: context,
- barrierDismissible: false,
- builder: (context) {
- _dialogContext = context;
-
- return LoadingDialog(
- title: Text("Chargement"),
- content: Text("Récupération des informations..."),
- );
- }
- ).whenComplete(() {
- _dialogContext = null;
- });
+ showLoadingDialog(
+ context,
+ title: 'Chargement',
+ content: 'Récupération des informations...',
+ onContextUpdate: (ctx) => _dialogContext = ctx
+ );
- login().then((_) => fetchState()).then((_) {
+ login().then((_) => fetchData()).then((_) {
if (_dialogContext == null) {
// TODO: Cancel login or prevent return
return;
}
Navigator.pop(_dialogContext);
- Navigator.pop(context);
- Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => HomePage(title: "Accueil")));
- }).catchError((e) {
- // TODO: Generify ?
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(builder: (context) => BasePage())
+ );
+ }).catchError((e, trace) async {
if (_dialogContext == null) {
return;
}
+ await cancelLogin();
+
Navigator.pop(_dialogContext);
- showDialog(
- context: context,
- builder: (BuildContext context) => AlertDialog(
- title: Text("Erreur"),
- content: Text("Impossible de se connecter au serveur : " + e.toString()),
- actions: [
- FlatButton(
- child: Text("OK :("),
- onPressed: () {
- Navigator.of(context).pop();
- },
- )
- ],
- )
+ Navigator.pop(context);
+
+ print('Error during login/data fetching : ' + e.toString());
+ print(trace);
+
+ showErrorDialog(
+ context,
+ title: 'Erreur',
+ content: 'Impossible de se connecter au serveur : ' + e.toString()
);
});
}
@@ -95,7 +101,8 @@ class _MSLoginPageState extends State
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: _onWebViewCreated,
javascriptChannels: Set.from([JavascriptChannel(
- name: "Epilyon", onMessageReceived: (message) => _onChannelMessage(context, message)
+ name: "Epilyon",
+ onMessageReceived: (message) => _onChannelMessage(context, message)
)]),
),
);
diff --git a/lib/pages/qcm/last_qcm.dart b/lib/pages/qcm/last_qcm.dart
index 8bfd6d9..7aa2f21 100644
--- a/lib/pages/qcm/last_qcm.dart
+++ b/lib/pages/qcm/last_qcm.dart
@@ -1,59 +1,135 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
import 'package:flutter/material.dart';
+import 'package:intl/intl.dart';
-import 'package:epilyon/state.dart';
+import 'package:epilyon/widgets/card.dart';
+import 'package:epilyon/data.dart';
-class LastQCMTab extends StatefulWidget
+class LastQCMPage extends StatefulWidget
{
- LastQCMTab({ Key key, this.title }) : super(key: key);
+ LastQCMPage({ Key key }) : super(key: key);
- final String title;
-
- @override
- _LastQCMTabState createState() => _LastQCMTabState();
+ @override
+ _LastQCMPageState createState() => _LastQCMPageState();
}
-class _LastQCMTabState extends State
+class _LastQCMPageState extends State
{
- double total;
-
- @override
- void initState()
- {
- super.initState();
+ Color greenGrade = Color(0xFF04C800);
+ Color redGrade = Color(0xFFD90000);
- Map marks = state['last_qcm']['values'];
- total = marks.values.fold(0, (a, b) => a + b) / 70.0 * 20.0; // TODO: Do that in server-side?
- }
+ @override
+ Widget build(BuildContext context)
+ {
+ QCM qcm = data.qcmHistory[0];
+ QCM previous = data.qcmHistory[1];
- @override
- Widget build(BuildContext context)
- {
- Map marks = state['last_qcm']['values'];
- var subjects = [];
+ // TODO: Handle cases where there is no QCM/Previous QCM
- for (var subject in marks.keys) {
- subjects.add(Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text(subject + " : ", style: TextStyle(fontSize: 16)),
- Text(marks[subject].toStringAsFixed(1) + "/10", style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16))
- ],
- ));
- }
+ DateFormat format = new DateFormat("dd MMMM yyyy", 'fr_FR');
- return Center(
- child: Column(
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.only(top: 30.0),
+ child: Column(
+ children: [
+ Text(
+ 'QCM du ' + format.format(qcm.date),
+ style: TextStyle(fontSize: 16),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(top: 20.0),
+ child: Text(
+ qcm.average.toStringAsFixed(1) + '/20',
+ style: TextStyle(fontSize: 52, fontWeight: FontWeight.bold),
+ ),
+ ),
+ Text(
+ 'Coefficienté',
+ style: TextStyle(fontSize: 16, fontStyle: FontStyle.italic),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(top: 7.5, bottom: 40.0),
+ child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
- Text(total.toStringAsFixed(2) + "/20", style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold)),
- Padding(
- padding: const EdgeInsets.only(top: 20.0),
- child: Column(
- children: subjects
- ),
- )
+ compare(qcm.average, previous.average),
+ Text('par rapport au précédent', style: TextStyle(fontSize: 18.0))
],
+ ),
),
- );
- }
+ EpiCard(
+ title: 'Notes par matières',
+ child: Padding(
+ padding: const EdgeInsets.only(left: 25.0, bottom: 10.0, right: 22.5),
+ child: Column(
+ children: qcm.grades.map((grade) {
+ QCMGrade last = previous.grades.firstWhere((g) => grade.subject == g.subject);
+
+ return Padding(
+ padding: const EdgeInsets.only(bottom: 8),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ grade.subject,
+ style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
+ ),
+ Row(
+ children: [
+ Padding(
+ padding: EdgeInsets.only(right: grade.grade == 10.0 ? 4.0 : 12.75),
+ child: compare(grade.grade, last.grade),
+ ),
+ Row(
+ children: [
+ Text(
+ grade.grade.toStringAsFixed(1),
+ style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
+ ),
+ Text('/10', style: TextStyle(fontSize: 17))
+ ],
+ )
+ ],
+ )
+ ],
+ ),
+ );
+ }).toList(),
+ ),
+ )
+ )
+ ],
+ ),
+ ),
+ );
+ }
+
+ Widget compare(double a, double b)
+ {
+ String sign = a < b ? '- ' : '+';
+ String grade = (a - b).abs().toStringAsFixed(1);
+ Color color = a > b ? greenGrade : (a < b ? redGrade : Colors.black);
+
+ return Padding(
+ padding: const EdgeInsets.only(right: 4.0),
+ child: Text("($sign$grade)", style: TextStyle(fontSize: 18.0, color: color)),
+ );
+ }
}
\ No newline at end of file
diff --git a/lib/pages/qcm/next_qcm.dart b/lib/pages/qcm/next_qcm.dart
deleted file mode 100644
index fa354da..0000000
--- a/lib/pages/qcm/next_qcm.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-import 'package:flutter/material.dart';
-
-class NextQCMTab extends StatefulWidget
-{
- NextQCMTab({ Key key, this.title }) : super(key: key);
-
- final String title;
-
- @override
- _NextQCMTabState createState() => _NextQCMTabState();
-}
-
-class _NextQCMTabState extends State
-{
- @override
- Widget build(BuildContext context)
- {
- return Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text("WIP")
- ],
- ),
- );
- }
-}
\ No newline at end of file
diff --git a/lib/pages/qcm/qcm.dart b/lib/pages/qcm/qcm.dart
deleted file mode 100644
index 8154596..0000000
--- a/lib/pages/qcm/qcm.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-import 'package:epilyon/pages/qcm/last_qcm.dart';
-import 'package:epilyon/pages/qcm/next_qcm.dart';
-import 'package:flutter/material.dart';
-import 'package:epilyon/widgets/layout/drawer.dart';
-
-class QCMPage extends StatefulWidget
-{
- QCMPage({ Key key }) : super(key: key);
-
- @override
- _QCMPageState createState() => _QCMPageState();
-}
-
-class _QCMPageState extends State
-{
- int _tabIndex;
-
- final List _titles = [
- "Prochain QCM",
- "Dernier QCM"
- ];
- final List _tabs = [
- NextQCMTab(),
- LastQCMTab()
- ];
-
- @override
- void initState()
- {
- super.initState();
-
- var h = DateTime.now().hour;
- _tabIndex = h >= 6 && h <= 12 ? 0 : 1;
- }
-
- void _onTabTap(int tab)
- {
- setState(() {
- _tabIndex = tab;
- });
- }
-
- @override
- Widget build(BuildContext context)
- {
- return Scaffold(
- appBar: AppBar(
- title: Text(_titles[_tabIndex]),
- ),
- body: _tabs[_tabIndex],
- drawer: EpilyonDrawer(),
- bottomNavigationBar: BottomNavigationBar(
- currentIndex: _tabIndex,
- onTap: _onTabTap,
- items: [
- BottomNavigationBarItem(
- icon: Icon(Icons.edit),
- title: Text("Prochain")
- ),
- BottomNavigationBarItem(
- icon: Icon(Icons.list),
- title: Text("Résultats"),
- ),
- BottomNavigationBarItem(
- icon: Icon(Icons.history),
- title: Text("Précédents")
- )
- ],
- )
- );
- }
-}
\ No newline at end of file
diff --git a/lib/pages/refresh.dart b/lib/pages/refresh.dart
new file mode 100644
index 0000000..b8f0c53
--- /dev/null
+++ b/lib/pages/refresh.dart
@@ -0,0 +1,77 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+import 'package:flutter/scheduler.dart';
+
+import 'package:epilyon/auth.dart';
+import 'package:epilyon/base.dart';
+import 'package:epilyon/data.dart';
+import 'package:epilyon/widgets/dialogs.dart';
+
+class RefreshPage extends StatefulWidget
+{
+ RefreshPage({Key key}) : super(key: key);
+
+ @override
+ _RefreshPageState createState() => _RefreshPageState();
+}
+
+class _RefreshPageState extends State
+{
+ BuildContext _dialogContext;
+
+ @override
+ void initState()
+ {
+ super.initState();
+
+ SchedulerBinding.instance.addPostFrameCallback((_) async {
+ if (!(await canRefresh())) {
+ pushBase(context);
+ return;
+ }
+
+ showLoadingDialog(
+ context,
+ title: 'Bienvenue',
+ content: "Chargement d'Epilyon...",
+ onContextUpdate: (ctx) => _dialogContext = ctx
+ );
+
+ refresh().then((_) => fetchData()).catchError((e, trace) async {
+ print('Error while doing refresh/fetching data : ' + e.toString());
+ print('Considering not logged');
+ print(trace);
+
+ await cancelLogin();
+ }).whenComplete(() {
+ if (_dialogContext == null) {
+ Navigator.pop(_dialogContext);
+ }
+
+ pushBase(context);
+ });
+ });
+ }
+
+ @override
+ Widget build(BuildContext context)
+ {
+ return Container();
+ }
+}
diff --git a/lib/state.dart b/lib/state.dart
deleted file mode 100644
index 1e7306b..0000000
--- a/lib/state.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'dart:convert';
-
-import 'package:http/http.dart' as http;
-
-import 'package:epilyon/api.dart';
-import 'package:epilyon/auth.dart';
-
-var state = {};
-
-Future fetchState() async {
- var result = await http.post(API_URL + '/state/get', headers: {
- "Authorization": "Bearer " + getToken()
- });
-
- state = jsonDecode(result.body)['state'];
-}
diff --git a/lib/widgets/button.dart b/lib/widgets/button.dart
new file mode 100644
index 0000000..a4db09a
--- /dev/null
+++ b/lib/widgets/button.dart
@@ -0,0 +1,54 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+
+class EpiButton extends StatelessWidget
+{
+ final GestureTapCallback onPressed;
+ final String text;
+
+ EpiButton({ @required this.onPressed, @required this.text });
+
+ @override
+ Widget build(BuildContext context)
+ {
+ return Material(
+ elevation: 0.0,
+ color: Theme.of(context).primaryColor,
+ borderRadius: BorderRadius.all(Radius.circular(4.0)),
+ child: InkWell(
+ onTap: onPressed,
+ borderRadius: BorderRadius.all(Radius.circular(4.0)),
+ child: Ink(
+ child: Center(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 10.0),
+ child: Text(
+ text,
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.w500,
+ fontSize: 18.0),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/card.dart b/lib/widgets/card.dart
new file mode 100644
index 0000000..dd4257e
--- /dev/null
+++ b/lib/widgets/card.dart
@@ -0,0 +1,56 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+
+class EpiCard extends StatelessWidget
+{
+ final String title;
+ final Widget child;
+ final bool fullSize;
+
+ EpiCard({ @required this.title, @required this.child, this.fullSize = true });
+
+ @override
+ Widget build(BuildContext context)
+ {
+ return Container(
+ width: fullSize ? MediaQuery.of(context).size.width - 30.0 : null,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.all(Radius.circular(3.0)),
+ boxShadow: [
+ BoxShadow(
+ offset: Offset(0, 3),
+ blurRadius: 8.0,
+ color: Color.fromRGBO(116, 129, 141, 0.1)
+ )
+ ]
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(left: 13.5, top: 11.5, bottom: 12.5),
+ child: Text(this.title, style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),),
+ ),
+ child
+ ],
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/dialogs.dart b/lib/widgets/dialogs.dart
new file mode 100644
index 0000000..8ae90e9
--- /dev/null
+++ b/lib/widgets/dialogs.dart
@@ -0,0 +1,86 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+
+void showLoadingDialog(BuildContext context, {
+ String title,
+ String content,
+ Function(BuildContext context) onContextUpdate
+})
+{
+ showDialog(
+ context: context,
+ barrierDismissible: false,
+ builder: (BuildContext context) {
+ onContextUpdate(context);
+
+ return LoadingDialog(
+ title: Text(title),
+ content: Text(content),
+ );
+ }
+ ).whenComplete(() {
+ onContextUpdate(null);
+ });
+}
+
+void showErrorDialog(BuildContext context, { String title, String content })
+{
+ showDialog(
+ context: context,
+ builder: (BuildContext context) => AlertDialog(
+ title: Text(title),
+ content: Text(content),
+ actions: [
+ FlatButton(
+ child: Text("OK :("),
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ )
+ ],
+ )
+ );
+}
+
+class LoadingDialog extends SimpleDialog
+{
+ LoadingDialog({
+ Widget title,
+ Widget content
+ }) : super(
+ title: title,
+ children: [
+ Padding(
+ // TODO: TEXT WRAPPING!
+ padding: const EdgeInsets.only(left: 32.5, right: 30, top: 12.5, bottom: 8.5),
+ child: Row(
+ children: [
+ CircularProgressIndicator(
+ value: null,
+ ),
+ Flexible(child: Padding(
+ padding: const EdgeInsets.only(left: 27.5),
+ child: content,
+ ))
+ ],
+ ),
+ )
+ ]
+ );
+}
diff --git a/lib/widgets/layout/drawer.dart b/lib/widgets/layout/drawer.dart
deleted file mode 100644
index 45c66bc..0000000
--- a/lib/widgets/layout/drawer.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'package:epilyon/auth.dart';
-import 'package:epilyon/pages/login.dart';
-import 'package:epilyon/pages/qcm/qcm.dart';
-import 'package:flutter/material.dart';
-
-class EpilyonDrawer extends StatelessWidget
-{
- // TODO: Instead use body variable changing
-
- @override
- Widget build(BuildContext context)
- {
- return Drawer(
- child: ListView(
- padding: EdgeInsets.zero,
- children: [
- DrawerHeader(
- child: Text("Epilyon ??"),
- decoration: BoxDecoration(
- color: Theme.of(context).primaryColor
- ),
- ),
- ListTile(
- leading: Icon(Icons.school),
- title: Text("Q.C.M."),
- onTap: () {
- Navigator.pop(context);
- Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => QCMPage()));
- },
- ),
- ListTile(
- leading: Icon(Icons.exit_to_app),
- title: Text("Se déconnecter"),
- onTap: () {
- logout().then((success) {
- // TODO: Loading
- if (success) {
- Navigator.pop(context);
- Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => LoginPage(title: "Epilyon")));
- }
- });
- }
- )
- ])
- );
- }
-}
\ No newline at end of file
diff --git a/lib/widgets/loading_dialog.dart b/lib/widgets/loading_dialog.dart
deleted file mode 100644
index da06038..0000000
--- a/lib/widgets/loading_dialog.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-import 'package:flutter/material.dart';
-
-// TODO: Simpler way ?
-
-class LoadingDialog extends SimpleDialog
-{
- LoadingDialog({
- Widget title,
- Widget content
- }) : super(
- title: title,
- children: [
- Padding(
- // TODO: TEXT WRAPPING!
- padding: const EdgeInsets.only(left: 32.5, right: 30, top: 12.5, bottom: 8.5),
- child: Row(
- children: [
- CircularProgressIndicator(
- value: null,
- ),
- Flexible(child: Padding(
- padding: const EdgeInsets.only(left: 27.5),
- child: content,
- ))
- ],
- ),
- )
- ]
- );
-}
\ No newline at end of file
diff --git a/lib/widgets/microsoft_button.dart b/lib/widgets/microsoft_button.dart
deleted file mode 100644
index 0880f0e..0000000
--- a/lib/widgets/microsoft_button.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'package:flutter/material.dart';
-
-class MicrosoftButton extends StatelessWidget
-{
- final GestureTapCallback onPressed;
- final String text;
-
- MicrosoftButton({ @required this.onPressed, @required this.text });
-
- @override
- Widget build(BuildContext context)
- {
- return Material(
- elevation: 15.0,
- color: Colors.black,
- child: InkWell(
- onTap: onPressed,
- child: Ink(
- height: 45.0,
- child: Center(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Padding(
- padding: const EdgeInsets.only(right: 10.0),
- child: Image(
- image: AssetImage("assets/ms_icon.png"),
- height: 21.0,
- width: 21.0,
- ),
- ),
- Text(
- text,
- // textAlign: TextAlign.center,
- style: TextStyle(
- color: Colors.white,
- fontWeight: FontWeight.normal,
- fontSize: 18.0),
- ),
- ],
- ),
- ),
- ),
- ),
- );
- }
-}
\ No newline at end of file
diff --git a/lib/widgets/office_button.dart b/lib/widgets/office_button.dart
new file mode 100644
index 0000000..5bf38e8
--- /dev/null
+++ b/lib/widgets/office_button.dart
@@ -0,0 +1,65 @@
+/*
+ * Epilyon, keeping EPITA students organized
+ * Copyright (C) 2019-2020 Adrien 'Litarvan' Navratil
+ *
+ * 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 .
+ */
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+class OfficeButton extends StatelessWidget
+{
+ final GestureTapCallback onPressed;
+ final String text;
+
+ OfficeButton({ @required this.onPressed, @required this.text });
+
+ @override
+ Widget build(BuildContext context)
+ {
+ return Material(
+ elevation: 15.0,
+ color: Colors.black,
+ child: InkWell(
+ onTap: onPressed,
+ child: Ink(
+ height: 45.0,
+ child: Center(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(right: 10.0),
+ child: SvgPicture.asset(
+ 'assets/icons/office.svg',
+ width: 21.0,
+ height: 21.0
+ ),
+ ),
+ Text(
+ text,
+ // textAlign: TextAlign.center,
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.normal,
+ fontSize: 18.0),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/pubspec.lock b/pubspec.lock
index 670c4fb..73f28af 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1,6 +1,20 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.11"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.5.2"
async:
dependency: transitive
description:
@@ -8,6 +22,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
+ boolean_selector:
+ dependency: transitive
+ description:
+ name: boolean_selector
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.5"
charcode:
dependency: transitive
description:
@@ -22,25 +43,56 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
+ convert:
+ dependency: transitive
+ description:
+ name: convert
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.1"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.3"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
- version: "0.1.2"
+ version: "0.1.3"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
+ flutter_svg:
+ dependency: "direct main"
+ description:
+ name: flutter_svg
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.17.1"
+ flutter_test:
+ dependency: "direct dev"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_web_plugins:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
http:
dependency: "direct main"
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
- version: "0.12.0+2"
+ version: "0.12.0+4"
http_parser:
dependency: transitive
description:
@@ -48,13 +100,34 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
+ image:
+ dependency: transitive
+ description:
+ name: image
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.4"
+ intl:
+ dependency: "direct main"
+ description:
+ name: intl
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.16.1"
+ matcher:
+ dependency: transitive
+ description:
+ name: matcher
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.12.6"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.7"
+ version: "1.1.8"
path:
dependency: transitive
description:
@@ -62,6 +135,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
+ path_drawing:
+ dependency: transitive
+ description:
+ name: path_drawing
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.4.1"
+ path_parsing:
+ dependency: transitive
+ description:
+ name: path_parsing
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.1.4"
pedantic:
dependency: transitive
description:
@@ -69,13 +156,55 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0+1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.4.0"
+ plugin_platform_interface:
+ dependency: transitive
+ description:
+ name: plugin_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.1"
+ quiver:
+ dependency: transitive
+ description:
+ name: quiver
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.5"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
- version: "0.5.4"
+ version: "0.5.6+1"
+ shared_preferences_macos:
+ dependency: transitive
+ description:
+ name: shared_preferences_macos
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.0.1+4"
+ shared_preferences_platform_interface:
+ dependency: transitive
+ description:
+ name: shared_preferences_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.1"
+ shared_preferences_web:
+ dependency: transitive
+ description:
+ name: shared_preferences_web
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.1.2+3"
sky_engine:
dependency: transitive
description: flutter
@@ -88,6 +217,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.5"
+ stack_trace:
+ dependency: transitive
+ description:
+ name: stack_trace
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.9.3"
+ stream_channel:
+ dependency: transitive
+ description:
+ name: stream_channel
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.0"
string_scanner:
dependency: transitive
description:
@@ -102,6 +245,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
+ test_api:
+ dependency: transitive
+ description:
+ name: test_api
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.11"
typed_data:
dependency: transitive
description:
@@ -109,6 +259,34 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
+ url_launcher:
+ dependency: "direct main"
+ description:
+ name: url_launcher
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "5.4.1"
+ url_launcher_macos:
+ dependency: transitive
+ description:
+ name: url_launcher_macos
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.0.1+2"
+ url_launcher_platform_interface:
+ dependency: transitive
+ description:
+ name: url_launcher_platform_interface
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.5"
+ url_launcher_web:
+ dependency: transitive
+ description:
+ name: url_launcher_web
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.1.0+2"
vector_math:
dependency: transitive
description:
@@ -122,7 +300,14 @@ packages:
name: webview_flutter
url: "https://pub.dartlang.org"
source: hosted
- version: "0.3.15+1"
+ version: "0.3.19+5"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.5.0"
sdks:
- dart: ">=2.2.2 <3.0.0"
- flutter: ">=1.6.7 <2.0.0"
+ dart: ">=2.5.0 <3.0.0"
+ flutter: ">=1.12.13+hotfix.5 <2.0.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index f820033..7a92337 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,19 +1,56 @@
-name: epilyon
-description: Keeping EPITA students organized
-version: 1.0.0+1
-
-environment:
- sdk: ">=2.1.0 <3.0.0"
-
-dependencies:
- flutter:
- sdk: flutter
- cupertino_icons: ^0.1.2
- webview_flutter: ^0.3.15+1
- http: ^0.12.0+2
- shared_preferences: ^0.5.4
-
-flutter:
- uses-material-design: true
- assets:
- - assets/
+name: epilyon
+description: Keeping EPITA students organized
+version: 0.1.0+1
+
+environment:
+ sdk: ">=2.1.0 <3.0.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+ cupertino_icons: ^0.1.2
+ flutter_svg: ^0.17.1
+ url_launcher: ^5.4.1
+ http: ^0.12.0+4
+ shared_preferences: ^0.5.6+1
+ webview_flutter: ^0.3.19+5
+ intl: ^0.16.1
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+
+flutter:
+ uses-material-design: true
+ assets:
+ - assets/icons/arrow_drop_down.svg
+ - assets/icons/brightness_3.svg
+ - assets/icons/build.svg
+ - assets/icons/check.svg
+ - assets/icons/check_box.svg
+ - assets/icons/done_all.svg
+ - assets/icons/edit.svg
+ - assets/icons/event_note.svg
+ - assets/icons/first_page.svg
+ - assets/icons/format_list_bulleted.svg
+ - assets/icons/info.svg
+ - assets/icons/landscape.svg
+ - assets/icons/last_page.svg
+ - assets/icons/list.svg
+ - assets/icons/menu.svg
+ - assets/icons/navigate_next.svg
+ - assets/icons/office.svg
+ - assets/icons/school.svg
+ - assets/icons/settings.svg
+ - assets/icons/wb_sunny.svg
+ - assets/icons/work.svg
+ - assets/images/default_user.png
+ fonts:
+ - family: Lato2
+ fonts:
+ - asset: assets/fonts/Lato_SemiBold.ttf
+ weight: 600
+ - family: Lato3
+ fonts:
+ - asset: assets/fonts/Lato_SemiBold_Italic.ttf
+ weight: 600
\ No newline at end of file