diff --git a/.gitignore b/.gitignore index c6cbe56..ef3a1fc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,51 @@ /local.properties /.idea/workspace.xml /.idea/libraries +/.idea/misc.xml +/.idea/vcs.xml .DS_Store /build /captures +/.idea +# Added by abhishek sachdeva +# Built application files +*.apk +*.ap_ + +# Files for the Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# Intellij +*.iml + +# Keystore files +*.jks + +sentry.properties diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 8162e9d..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -BookShareApp \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/encodings.xml similarity index 52% rename from .idea/vcs.xml rename to .idea/encodings.xml index 6564d52..97626ba 100644 --- a/.idea/vcs.xml +++ b/.idea/encodings.xml @@ -1,6 +1,6 @@ - - + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index ac122f4..bc3eb86 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -3,10 +3,8 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 5d19981..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..dbbe355 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 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 Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are 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. + + 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. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + 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 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 work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + 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 AGPL, see +. diff --git a/app/build.gradle b/app/build.gradle index 7557db7..5581feb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,28 +1,98 @@ apply plugin: 'com.android.application' +apply plugin: 'realm-android' +apply plugin: 'io.sentry.android.gradle' android { - compileSdkVersion 23 - buildToolsVersion "19.1.0" - + compileSdkVersion 25 + buildToolsVersion '25.0.2' + useLibrary 'org.apache.http.legacy' defaultConfig { - applicationId "com.example.abhishek.bookshareapp" - minSdkVersion 15 - targetSdkVersion 23 - versionCode 1 - versionName "1.0" + applicationId "com.sdsmdg.bookshareapp.BSA" + minSdkVersion 19 + targetSdkVersion 25 + versionCode 6 + versionName "0.8.2" + multiDexEnabled true + + def sentryFile = project.rootProject.file("sentry.properties") + + if (sentryFile.exists()) { + def sentryProperites = new Properties() + sentryProperites.load(sentryFile.newInputStream()) + buildConfigField "String", "SENTRY_DSN", formatStringField(sentryProperites["dsn"]) + } else { + buildConfigField "String", "SENTRY_DSN", "\"\"" + } } buildTypes { release { - minifyEnabled false + shrinkResources true + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + dexOptions { + javaMaxHeapSize "4g" + jumboMode true + } +} + +def formatStringField(field) { + return "\"${field}\"" +} + +sentry { + // Disables or enables the automatic configuration of proguard + // for Sentry. This injects a user_default_image config for proguard so + // you don't need to do it manually. + autoProguardConfig true + + // Enables or disables the automatic upload of mapping files + // during a build. If you disable this you'll need to manually + // upload the mapping files with sentry-cli when you do a release. + autoUpload true +} + +configurations { + compile.exclude group: "org.apache.httpcomponents", module: "httpclient" } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) + compile fileTree(include: ['*.jar'], dir: 'libs') + compile('com.squareup.retrofit2:converter-simplexml:2.1.0') { + exclude module: 'stax' + exclude module: 'stax-api' + exclude module: 'xpp3' + } + debugCompile 'com.readystatesoftware.chuck:library:1.1.0' + releaseCompile 'com.readystatesoftware.chuck:library-no-op:1.1.0' + compile 'com.journeyapps:zxing-android-embedded:3.3.0' + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:customtabs:25.3.1' + compile 'com.android.support:design:25.3.1' + compile 'com.android.support:cardview-v7:25.3.1' + compile 'com.android.support:palette-v7:25.3.1' + compile 'com.android.support:recyclerview-v7:25.3.1' + compile 'com.android.support:support-v4:25.3.1' + compile 'id.zelory:compressor:1.0.2' + compile 'de.hdodenhof:circleimageview:2.1.0' + compile 'com.squareup.okhttp3:logging-interceptor:3.8.0' + compile 'com.squareup.retrofit2:retrofit:2.3.0' + compile 'com.jakewharton:butterknife:6.1.0' + compile 'com.squareup.retrofit2:converter-gson:2.3.+' + compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2' + compile 'com.squareup.picasso:picasso:2.5.2' + compile 'jp.wasabeef:blurry:2.0.2' + compile 'com.google.api-client:google-api-client:1.20.0' + compile 'com.google.firebase:firebase-messaging:10.0.1' + compile 'com.airbnb.android:lottie:1.5.1' + compile 'com.android.support.constraint:constraint-layout:1.0.2' + compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' + compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' + compile 'io.sentry:sentry-android:1.5.3' + compile 'io.reactivex.rxjava2:rxandroid:2.0.1' + compile 'io.reactivex.rxjava2:rxjava:2.1.8' testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:23.1.1' - compile 'com.android.support:design:23.1.1' - compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3' - compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'} +} + +apply plugin: 'com.google.gms.google-services' diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..e1c68c5 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "382150189103", + "firebase_url": "https://book-share-d31a2.firebaseio.com", + "project_id": "book-share-d31a2", + "storage_bucket": "book-share-d31a2.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:382150189103:android:5c58e431abcdb76b", + "android_client_info": { + "package_name": "com.sdsmdg.bookshareapp.BSA" + } + }, + "oauth_client": [ + { + "client_id": "382150189103-l0dg8v5rdvcrpqlchteu9i69qo5m4fae.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDGzc_Zwz7Bua10laovgn9whymQjfibiPE" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f79e1d1..c212a9e 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -15,3 +15,71 @@ #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} + +-dontwarn com.squareup.okhttp.** + +# Platform calls Class.forName on types which do not exist on Android to determine platform. +-dontnote retrofit2.Platform +# Platform used when running on Java 8 VMs. Will not be used at runtime. +-dontwarn retrofit2.Platform$Java8 +# Retain generic type information for use by reflection by converters and adapters. +-keepattributes Signature +# Retain declared checked exceptions for use by a Proxy instance. +-keepattributes Exceptions + +# Retain generated class which implement Unbinder. +-keep public class * implements butterknife.Unbinder { public (**, android.view.View); } + +# Prevent obfuscation of types which use ButterKnife annotations since the simple name +# is used to reflectively look up the generated ViewBinding. +-keep class butterknife.* +-keepclasseswithmembernames class * { @butterknife.* ; } +-keepclasseswithmembernames class * { @butterknife.* ; } + +-dontwarn butterknife.internal.** + +-keep class **$$ViewInjector { *; } + +-keepnames class * { @butterknife.InjectView *;} + +-dontwarn butterknife.Views$InjectViewProcessor + +-dontwarn com.gc.materialdesign.views.** + +-dontwarn okio.** +-dontwarn sun.misc.** + +-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { + long producerIndex; + long consumerIndex; +} + +-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { + rx.internal.util.atomic.LinkedQueueNode producerNode; +} + +-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { + rx.internal.util.atomic.LinkedQueueNode consumerNode; +} + +-dontnote rx.internal.util.PlatformDependent + + +-dontwarn org.slf4j.** + +-keep class android.support.v7.widget.SearchView { *; } + +-keep class io.realm.annotations.RealmModule +-keep @io.realm.annotations.RealmModule class * +-dontwarn javax.** +-dontwarn io.realm.** + +-keepattributes LineNumberTable,SourceFile +-dontwarn org.slf4j.** +-dontwarn javax.** + +-keep public class org.simpleframework.**{ *; } +-keep class org.simpleframework.xml.**{ *; } +-keep class org.simpleframework.xml.core.**{ *; } +-keep class org.simpleframework.xml.util.**{ *; } +-keep class com.sdsmdg.bookshareapp.BSA.api.models.* diff --git a/app/src/androidTest/java/com/example/abhishek/bookshareapp/ApplicationTest.java b/app/src/androidTest/java/com/sdsmdg/bookshareapp/BSA/ApplicationTest.java similarity index 88% rename from app/src/androidTest/java/com/example/abhishek/bookshareapp/ApplicationTest.java rename to app/src/androidTest/java/com/sdsmdg/bookshareapp/BSA/ApplicationTest.java index 99c07bb..7447043 100644 --- a/app/src/androidTest/java/com/example/abhishek/bookshareapp/ApplicationTest.java +++ b/app/src/androidTest/java/com/sdsmdg/bookshareapp/BSA/ApplicationTest.java @@ -1,4 +1,4 @@ -package com.example.abhishek.bookshareapp; +package com.sdsmdg.bookshareapp.BSA; import android.app.Application; import android.test.ApplicationTestCase; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3157953..4960b81 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,19 +1,75 @@ + package="com.sdsmdg.bookshareapp.BSA"> + + + + + + + android:theme="@style/AppTheme"> + + + + + + + + + + + + + + + + + + + + android:name=".ui.MyProfile" + android:label="My Profile" + android:screenOrientation="portrait" /> + + + @@ -21,16 +77,89 @@ + android:name=".ui.EditProfileActivity" + android:label="Edit your details" + android:parentActivityName=".ui.MyProfile" + android:screenOrientation="portrait" /> + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/Book.java b/app/src/main/java/com/example/abhishek/bookshareapp/Book.java deleted file mode 100644 index 4e02b33..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/Book.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.abhishek.bookshareapp; - -import java.util.List; - -/** - * Created by abhishek on 30/1/16. - */ - -public class Book { - private int ISBN; - private String title; - private String id; - VolumeInfo volumeInfo; - public int getISBN(){ - return ISBN; - } - - public void setISBN(int ISBN){ - this.ISBN=ISBN; - } - - public String getTitle(){ - return title; - } - - public void setTitle(String title){ - this.title=title; - } - - public void setID(String id){ - this.id=id; - } - - public String getId() { - return id; - } - - public VolumeInfo getInfo(){ - return volumeInfo; - } -} - - diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/BookResponse.java b/app/src/main/java/com/example/abhishek/bookshareapp/BookResponse.java deleted file mode 100644 index 1f99fc4..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/BookResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.example.abhishek.bookshareapp; - -import java.util.List; - -/** - * Created by abhishek on 10/2/16. - */ -public class BookResponse { - - private String kind; - - private int totalItems; - - private List items; - - public String getKind() { - return kind; - } - - public int getTotalItems() { - return totalItems; - } - - public List getItems() { - return items; - } -} diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/BooksAPI.java b/app/src/main/java/com/example/abhishek/bookshareapp/BooksAPI.java deleted file mode 100644 index 2d3f875..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/BooksAPI.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.abhishek.bookshareapp; - -/** - * Created by abhishek on 30/1/16. - */ - -import java.util.List; - -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.http.GET; -import retrofit2.http.Path; -import retrofit2.http.Query; - - -public interface BooksAPI { - - @GET("books/v1/volumes") - Call getBooks( - @Query("q") String isbn - ); - -} diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/BooksAdapter.java b/app/src/main/java/com/example/abhishek/bookshareapp/BooksAdapter.java deleted file mode 100644 index 53cddd9..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/BooksAdapter.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.abhishek.bookshareapp; - -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; - -/** - * Created by abhishek on 30/1/16. - */ -public class BooksAdapter extends BaseAdapter { - - @Override - public int getCount() { - return 0; - } - - @Override - public Object getItem(int position) { - return null; - } - - @Override - public long getItemId(int position) { - return 0; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - return null; - } -} diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/CommonUtilities.java b/app/src/main/java/com/example/abhishek/bookshareapp/CommonUtilities.java deleted file mode 100644 index 02875b3..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/CommonUtilities.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.abhishek.bookshareapp; - -/** - * Created by manchanda on 25/2/16. - */ -public class CommonUtilities { - - static final String google_api_url="https://www.googleapis.com/"; - -} diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/MainActivity.java b/app/src/main/java/com/example/abhishek/bookshareapp/MainActivity.java deleted file mode 100644 index 34ad079..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/MainActivity.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.example.abhishek.bookshareapp; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.util.Log; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - -import java.util.List; - -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.GsonConverterFactory; -import retrofit2.Retrofit; - -import static com.example.abhishek.bookshareapp.CommonUtilities.google_api_url; - - -public class MainActivity extends AppCompatActivity { - - public static final String TAG = MainActivity.class.getSimpleName(); - - ListView listview; - List books; - String query; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - final EditText search=(EditText)findViewById(R.id.search); - Button button= (Button)findViewById(R.id.button); - query= "isbn:"; - - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent i= new Intent(MainActivity.this,SearchResults.class); - query+=search.getText(); - Log.d("querymain",query); - i.putExtra("query",query); - startActivity(i); - } - }); - - String isbn= "9780553819229"; - listview= (ListView)findViewById(R.id.listview); - - //getBooks("isbn:"+isbn); - - - - - - } - - public void getBooks(String query){ - - Retrofit retrofit = new Retrofit.Builder() - .baseUrl(google_api_url) - .addConverterFactory(GsonConverterFactory.create()) - .build(); - - BooksAPI api = retrofit.create(BooksAPI.class); - - Call call = api.getBooks(query); - call.enqueue(new Callback() { - @Override - public void onResponse(retrofit2.Response response) { - List list = response.body().getItems(); - - Log.i(TAG, list.toString()); - Log.i("list", String.valueOf(list.size())); - Toast.makeText(MainActivity.this, String.valueOf(list.size()), Toast.LENGTH_SHORT).show(); - Book bk = list.get(0); - String id = bk.getId(); - Toast.makeText(MainActivity.this, id, Toast.LENGTH_SHORT).show(); - VolumeInfo vinfo1 = bk.getInfo(); - try { - Log.d("vinfo", vinfo1.getTitle()); - } catch (Exception e) { - Log.d("abcd", e.toString()); - } - // Toast.makeText(MainActivity.this,vi.get(0).getTitle(),Toast.LENGTH_SHORT).show(); - Log.i("resp", id); - } - - @Override - public void onFailure(Throwable t) { - Log.i("fail", "no resp"); - } - }); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - - //noinspection SimplifiableIfStatement - if (id == R.id.action_settings) { - return true; - } - - return super.onOptionsItemSelected(item); - } -} diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/SearchResults.java b/app/src/main/java/com/example/abhishek/bookshareapp/SearchResults.java deleted file mode 100644 index 36ddf3e..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/SearchResults.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.example.abhishek.bookshareapp; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.os.PersistableBundle; -import android.support.v7.app.AppCompatActivity; -import android.util.Log; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - -import org.w3c.dom.Text; - -import java.util.List; - -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.GsonConverterFactory; -import retrofit2.Retrofit; -import static com.example.abhishek.bookshareapp.CommonUtilities.google_api_url; - -/** - * Created by abhishek on 13/2/16. - */ -public class SearchResults extends AppCompatActivity { - String id; - String query; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.search_results); - ListView results_list= (ListView)findViewById(R.id.results_list); - TextView test =(TextView)findViewById(R.id.testing); - test.setText("Check"); - Intent i= getIntent(); - query=i.getStringExtra("query"); - Log.d("querysearch", query); - getBooks(query); - - } - - public void getBooks(String query){ - - Retrofit retrofit = new Retrofit.Builder() - .baseUrl(google_api_url) - .addConverterFactory(GsonConverterFactory.create()) - .build(); - - BooksAPI api = retrofit.create(BooksAPI.class); - - Call call = api.getBooks(query); - call.enqueue(new Callback() { - @Override - public void onResponse(retrofit2.Response response) { - List list = response.body().getItems(); - - Log.i("searchlist", String.valueOf(list.size())); - Book bk = list.get(0); - id = bk.getId(); - VolumeInfo vinfo1 = bk.getInfo(); - try { - Log.d("searchvinfo", vinfo1.getTitle()); - } catch (Exception e) { - Log.d("searchabcd", e.toString()); - } - Log.i("searchresp", id); - } - - @Override - public void onFailure(Throwable t) { - Log.i("searchfail", "no resp"); - } - }); - Toast.makeText(this ,id,Toast.LENGTH_SHORT).show(); - - } - -} diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/ServiceGenerator.java b/app/src/main/java/com/example/abhishek/bookshareapp/ServiceGenerator.java deleted file mode 100644 index 3802d00..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/ServiceGenerator.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.abhishek.bookshareapp; - -import okhttp3.OkHttpClient; -import retrofit2.GsonConverterFactory; -import retrofit2.Retrofit; -import retrofit2.CallAdapter; -import static com.example.abhishek.bookshareapp.CommonUtilities.google_api_url; -/** - * Created by abhishek on 23/1/16. - */ -public class ServiceGenerator { - - static String API_BASE_URL = google_api_url+"books/v1/volumes?q=isbn:9780553819229"; - - private static OkHttpClient httpClient = new OkHttpClient(); - private static Retrofit.Builder builder = - new Retrofit.Builder() - .baseUrl(API_BASE_URL) - .addConverterFactory(GsonConverterFactory.create()); - - - public static S createService(Class serviceClass) { - Retrofit retrofit = builder.client(httpClient).build(); - return retrofit.create(serviceClass); - } -} diff --git a/app/src/main/java/com/example/abhishek/bookshareapp/VolumeInfo.java b/app/src/main/java/com/example/abhishek/bookshareapp/VolumeInfo.java deleted file mode 100644 index 236f0aa..0000000 --- a/app/src/main/java/com/example/abhishek/bookshareapp/VolumeInfo.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.abhishek.bookshareapp; - -/** - * Created by abhishek on 10/2/16. - */ -public class VolumeInfo { - private String title; - - - public String getTitle(){ - return title; - } -} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/BSApplication.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/BSApplication.java new file mode 100644 index 0000000..0b6219a --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/BSApplication.java @@ -0,0 +1,32 @@ +package com.sdsmdg.bookshareapp.BSA; + +import android.app.Application; + +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; + +import io.realm.Realm; +import io.realm.RealmConfiguration; +import io.sentry.Sentry; +import io.sentry.android.AndroidSentryClientFactory; + +/** + * Created by ajayrahul on 26/9/17. + */ + +public class BSApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + NetworkingFactory.init(this); + if (!BuildConfig.DEBUG) { + Sentry.init(BuildConfig.SENTRY_DSN, new AndroidSentryClientFactory(this)); + } + Realm.init(this); + + RealmConfiguration realmConfiguration = new RealmConfiguration + .Builder() + .deleteRealmIfMigrationNeeded() + .build(); + Realm.setDefaultConfiguration(realmConfiguration); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/EndlessScrollListener.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/EndlessScrollListener.java new file mode 100644 index 0000000..5a2c018 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/EndlessScrollListener.java @@ -0,0 +1,105 @@ +package com.sdsmdg.bookshareapp.BSA.Listeners; + +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.StaggeredGridLayoutManager; + +public abstract class EndlessScrollListener extends RecyclerView.OnScrollListener { + // The minimum amount of items to have below your current scroll position + // before loading more. + private int visibleThreshold = 5; + // The current offset index of data you have loaded + private int currentPage = 0; + // The total number of items in the dataset after the last load + private int previousTotalItemCount = 0; + // True if we are still waiting for the last set of data to load. + private boolean loading = true; + // Sets the starting page index + private int startingPageIndex = 0; + + RecyclerView.LayoutManager mLayoutManager; + + public void reset() { + currentPage = 0; + previousTotalItemCount = 0; + loading = true; + startingPageIndex = 0; + } + + public EndlessScrollListener(LinearLayoutManager layoutManager) { + this.mLayoutManager = layoutManager; + } + + public EndlessScrollListener(GridLayoutManager layoutManager) { + this.mLayoutManager = layoutManager; + visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); + } + + public EndlessScrollListener(StaggeredGridLayoutManager layoutManager) { + this.mLayoutManager = layoutManager; + visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); + } + + public int getLastVisibleItem(int[] lastVisibleItemPositions) { + int maxSize = 0; + for (int i = 0; i < lastVisibleItemPositions.length; i++) { + if (i == 0) { + maxSize = lastVisibleItemPositions[i]; + } else if (lastVisibleItemPositions[i] > maxSize) { + maxSize = lastVisibleItemPositions[i]; + } + } + return maxSize; + } + + // This happens many times a second during a scroll, so be wary of the code you place here. + // We are given a few useful parameters to help us work out if we need to load some more data, + // but first we check if we are waiting for the previous load to finish. + @Override + public void onScrolled(RecyclerView view, int dx, int dy) { + int lastVisibleItemPosition = 0; + int totalItemCount = mLayoutManager.getItemCount(); + + if (mLayoutManager instanceof StaggeredGridLayoutManager) { + int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null); + // get maximum element within the list + lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions); + } else if (mLayoutManager instanceof LinearLayoutManager) { + lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition(); + } else if (mLayoutManager instanceof GridLayoutManager) { + lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition(); + } + + // If the total item count is zero and the previous isn't, assume the + // list is invalidated and should be reset back to initial state + if (totalItemCount < previousTotalItemCount) { + this.currentPage = this.startingPageIndex; + this.previousTotalItemCount = totalItemCount; + if (totalItemCount == 0) { + this.loading = true; + } + } + // If it’s still loading, we check to see if the dataset count has + // changed, if so we conclude it has finished loading and update the current page + // number and total item count. + if (loading && (totalItemCount > previousTotalItemCount)) { + loading = false; + previousTotalItemCount = totalItemCount; + } + + // If it isn’t currently loading, we check to see if we have breached + // the visibleThreshold and need to reload more data. + // If we do need to reload some more data, we execute onLoadMore to fetch the data. + // threshold should reflect how many total columns there are too + if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) { + currentPage++; + onLoadMore(currentPage, totalItemCount); + loading = true; + } + } + + // Defines the process for actually loading more data based on page + public abstract void onLoadMore(int page, int totalItemsCount); + +} \ No newline at end of file diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/SmsListener.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/SmsListener.java new file mode 100644 index 0000000..2a2d8a9 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/SmsListener.java @@ -0,0 +1,9 @@ +package com.sdsmdg.bookshareapp.BSA.Listeners; + +/** + * Created by harshit on 4/10/17. + */ + +public interface SmsListener { + void messageReceived(String messageText); +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/SmsReceiver.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/SmsReceiver.java new file mode 100644 index 0000000..f9610fd --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/Listeners/SmsReceiver.java @@ -0,0 +1,43 @@ +package com.sdsmdg.bookshareapp.BSA.Listeners; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.telephony.SmsMessage; + +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; + +/** + * Created by harshit on 4/10/17. + */ + +public class SmsReceiver extends BroadcastReceiver { + + private static SmsListener mListener; + + @Override + public void onReceive(Context context, Intent intent) { + + Bundle data = intent.getExtras(); + // bundle contains protocol data unit + // objects used in sending mails. + Object[] pdus = (Object[]) data.get("pdus"); + + if (pdus != null) { + for (int i = 0; i < pdus.length; i++) { + SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]); + //You must check here if the sender is your provider and not another one with same text. + String messageBody = smsMessage.getMessageBody(); + if (messageBody.startsWith(CommonUtilities.MESSAGE_BODY_PREFIX)) { + //Pass on the text to our listener. + mListener.messageReceived(messageBody); + } + } + } + } + + public static void bindListener(SmsListener listener) { + mListener = listener; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/BooksAPI.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/BooksAPI.java new file mode 100644 index 0000000..12d048e --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/BooksAPI.java @@ -0,0 +1,38 @@ +package com.sdsmdg.bookshareapp.BSA.api; + +import com.sdsmdg.bookshareapp.BSA.api.models.GoodreadsResponse; +import com.sdsmdg.bookshareapp.BSA.api.models.GoodreadsResponse2; +import com.sdsmdg.bookshareapp.BSA.api.models.GoodreadsResponse3; + +import java.util.HashMap; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; +import retrofit2.http.QueryMap; + +public interface BooksAPI { + + @GET("search.xml") + Call getBooks( + @Query("q") String keyword, + @Query("search[field]") String field, + @Query("key") String key + ); + + + @GET("book/show.xml") + Call getBookDescription( + @Query("id") Integer id, + @Query("key") String key + ); + + @GET("review/list.xml") + Call getToRead( + @QueryMap HashMap params + ); + + +} + + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/NetworkingFactory.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/NetworkingFactory.java new file mode 100644 index 0000000..54155bb --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/NetworkingFactory.java @@ -0,0 +1,64 @@ +package com.sdsmdg.bookshareapp.BSA.api; + +import android.content.Context; + +import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import com.readystatesoftware.chuck.ChuckInterceptor; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; + +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; +import retrofit2.converter.simplexml.SimpleXmlConverterFactory; + +public class NetworkingFactory { + + private BooksAPI booksAPI; + private UsersAPI usersAPI; + private Retrofit retrofit; + + private static NetworkingFactory grInstance; + private static NetworkingFactory localInstance; + + public static void init(Context context) { + grInstance = new NetworkingFactory(context, CommonUtilities.goodreads_api_url, false); + localInstance = new NetworkingFactory(context, CommonUtilities.local_books_api_url, true); + } + + public static NetworkingFactory getGRInstance() { + return grInstance; + } + + public static NetworkingFactory getLocalInstance() { + return localInstance; + } + + private NetworkingFactory(Context context, String url, boolean json) { + OkHttpClient.Builder httpclient = new OkHttpClient.Builder().addInterceptor(new ChuckInterceptor(context)); + if (json) { + retrofit = new Retrofit.Builder() + .baseUrl(url) + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .client(httpclient.build()) + .build(); + } else { + retrofit = new Retrofit.Builder() + .baseUrl(url) + .addConverterFactory(SimpleXmlConverterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .client(httpclient.build()) + .build(); + } + } + + public BooksAPI getBooksApi() { + booksAPI = retrofit.create(BooksAPI.class); + return booksAPI; + } + + public UsersAPI getUsersAPI() { + usersAPI = retrofit.create(UsersAPI.class); + return usersAPI; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/UsersAPI.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/UsersAPI.java new file mode 100644 index 0000000..e633bb3 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/UsersAPI.java @@ -0,0 +1,277 @@ +package com.sdsmdg.bookshareapp.BSA.api; + +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookAddDeleteResponse; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookDetailWithCancel; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookList; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.RemoveBook; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserDetailWithCancel; +import com.sdsmdg.bookshareapp.BSA.api.models.Login; +import com.sdsmdg.bookshareapp.BSA.api.models.Notification.Notification_Model; +import com.sdsmdg.bookshareapp.BSA.api.models.Notification.Notifications; +import com.sdsmdg.bookshareapp.BSA.api.models.Signup; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; +import com.sdsmdg.bookshareapp.BSA.api.models.UserImageResult; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.ui.College; + +import java.util.List; + +import io.reactivex.Observable; +import okhttp3.MultipartBody; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.PUT; +import retrofit2.http.Part; +import retrofit2.http.Path; +import retrofit2.http.Query; + + +public interface UsersAPI { + @FormUrlEncoded + @POST("users/reg/?format=json") + Call getUserInfo( + @Field("email") String email, + @Field("hostel") String hostel, + @Field("room_no") String roomNo, + @Field("enr_no") String enrNo, + @Field("first_name") String firstName, + @Field("last_name") String lastName, + @Field("contact_no") String contactNo, + @Field("fcm_id") String fcm_id, + @Field("password") String password, + @Query("college_name") String college + ); + + @FormUrlEncoded + @POST("login/") + Call getToken( + @Field("email") String email, + @Field("password") String password + ); + + @GET("books/?format=json") + Call> getBooksList( + @Header("Authorization") String token + ); + + @GET("local-books/") + Call getLocalBList( + @Query("page") String page, + @Header("Authorization") String token + ); + + @GET("books/?format=json") + Call getBList( + @Query("page") String page, + @Header("Authorization") String token + ); + + @GET("guest/?format=json") + Call getGuestBList( + @Query("page") String page + ); + + @FormUrlEncoded + @POST("college/") + Call addCollege( + @Field("name") String college, + @Field("domain") String domain + ); + + @FormUrlEncoded + @POST("books/?format=json") + Call addBook( + @Field("email") String email, + @Field("title") String title, + @Field("author") String author, + @Field("gr_id") String gr_id, + @Field("ratings_count") Long ratingsCount, + @Field("rating") Float rating, + @Field("gr_img_url") String gr_img_url, + @Field("description") String description, + @Header("Authorization") String token + ); + + @GET("book/{id}/?format=json") + Call getBookDetails( + @Path("id") String id, + @Query("book_id") String id_same, + @Header("Authorization") String token + ); + + @GET("user/{id}/?format=json") + Call getUserDetails( + @Path("id") String id, + @Query("user_id") String id_same, + @Header("Authorization") String token + ); + + @POST("token/") + Call getUserEmail(@Header("Authorization") String token); + + @GET("notifications/") + Call getNotifs( + @Query("page") String count, + @Header("Authorization") String token + ); + + @FormUrlEncoded + @POST("notifications/") + Call sendNotif( + @Field("sender_id") String senderId, + @Field("sender_name") String senderName, + @Field("book_id") String bookId, + @Field("book_title") String bookTitle, + @Field("process") String process, + @Field("target_id") String targetId, + @Field("message") String message, + @Header("Authorization") String token + ); + + @FormUrlEncoded + @POST("notifications/") + Call acceptNotif( + @Field("notif_id") String notifId, + @Field("sender_id") String senderId, + @Field("sender_name") String senderName, + @Field("book_id") String bookId, + @Field("book_title") String bookTitle, + @Field("process") String process, + @Field("target_id") String targetId, + @Field("message") String message, + @Header("Authorization") String token + ); + + @FormUrlEncoded + @POST("notifications/") + Call rejectNotif( + @Field("notif_id") String notifId, + @Field("process") String process, + @Field("message") String message, + @Header("Authorization") String token + ); + + @FormUrlEncoded + @POST("notifications/") + Call cancelNotif( + @Field("book_id") String bookId, + @Field("receiver_id") String targetId, + @Field("process") String process, + @Header("Authorization") String token + ); + + @PUT("user/{id}/") + Call editUserDetails( + @Header("Authorization") String token, + @Path("id") String id, + @Body UserInfo userInfo + ); + + @FormUrlEncoded + @POST("logout/") + Call logout( + @Header("Authorization") String token, + @Field("fcm_id") String fcm_id + ); + + @FormUrlEncoded + @POST("password/change/") + Call changePassword( + @Header("Authorization") String token, + @Field("old_password") String oldPassword, + @Field("new_password") String newPassword + ); + + @FormUrlEncoded + @POST("fcmid/change/") + Call update_fcm_id( + @Header("Authorization") String token, + @Field("fcm_id") String fcm_id + ); + + + @PUT("books/") + Call removeBook( + @Body RemoveBook removeBook, + @Header("Authorization") String token + ); + + @GET("search/") + Observable> search( + @Query("search") String searchQuery, + @Header("Authorization") String token + ); + + @GET("search-user/") + Observable> searchUser( + @Query("search") String searchQuery, + @Header("Authorization") String token + ); + + @GET("search-college/") + Call> searchCollege( + @Query("search") String college + ); + + @Multipart + @POST("/image/{id}/") + Call uploadImage(@Header("Authorization") String token, + @Part MultipartBody.Part file, + @Path("id") String id); + + @FormUrlEncoded + @POST("/me/password/reset/") + Call sendForgotPasswordMail( + @Field("email") String email + ); + + @FormUrlEncoded + @POST("/new_activation/") + Call sendNewActivationMail( + @Field("email") String email + ); + + @FormUrlEncoded + @POST("/resend_otp/") + Call sendNewOtp( + @Field("email") String email + ); + + @FormUrlEncoded + @POST("/me/password/reset/confirm/") + Call confirmPassword( + @Field("uidb64") String uidb64, + @Field("token") String token, + @Field("new_password") String newPassword, + @Field("confirm_password") String confirmPassword + ); + + @GET("/phone-activation/{key}") + Call checkActivation( + @Path("key") String key + ); + + @FormUrlEncoded + @POST("/verify_otp/") + Call verifyOtp( + @Field("email") String email, + @Field("otp") String otp + ); + + @FormUrlEncoded + @POST("/change-mobile/") + Call changeMobile( + @Header("Authorization") String token, + @Field("email") String email, + @Field("contact_no") String contactNo, + @Field("otp") String otp + ); +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Author.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Author.java new file mode 100644 index 0000000..dda000d --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Author.java @@ -0,0 +1,15 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "author", strict = false) +public class Author { + + @Element(name = "name") + public String author_name; + + public String getAuthor_name() { + return author_name; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Authors.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Authors.java new file mode 100644 index 0000000..879ac62 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Authors.java @@ -0,0 +1,14 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "authors", strict = false) +public class Authors { + @Element(name = "author") + public Author author; + + public Author getAuthors() { + return author; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Book.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Book.java new file mode 100644 index 0000000..ec140d0 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Book.java @@ -0,0 +1,47 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "work", strict = false) +public class Book { + + @Element(name = "best_book") + BookDetails bookDetails; + + @Element(name = "id") + public Integer search_id; + + @Element(name = "books_count") + public String page_count; + + @Element(name = "average_rating") + public float rating; + + @Element(name = "ratings_count") + public long ratingCount; + + public BookDetails getBookDetails() { + return bookDetails; + } + + public Integer getId() { + return search_id; + } + + public String getPage_count() { + return page_count; + } + + public float getRating() { + return rating; + } + + public long getRatingCount() { + return ratingCount; + } +} + + + + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDescription.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDescription.java new file mode 100644 index 0000000..9eed56c --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDescription.java @@ -0,0 +1,19 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "book", strict = false) +public class BookDescription { + + @Element(name = "description") + public String BDescription; + + public String getBDescription() { + return BDescription; + } +} + + + + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDetails.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDetails.java new file mode 100644 index 0000000..26383d9 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDetails.java @@ -0,0 +1,45 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "best_book", strict = false) +public class BookDetails { + + @Element(name = "title") + public String title; + + @Element(name = "id") + public Integer search_id; + + @Element(name = "image_url") + public String image_url; + + @Element(name = "small_image_url") + public String small_image_url; + + @Element(name = "author") + Author author; + + public Integer getId() { + return search_id; + } + + public String getTitle() { + return title; + } + + public String getImage_url() { + return image_url; + } + + public String getSmall_image_url() { + return small_image_url; + } + + public Author getAuthor() { + return author; + } + + +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDetailsToRead.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDetailsToRead.java new file mode 100644 index 0000000..92f0d67 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/BookDetailsToRead.java @@ -0,0 +1,53 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "book", strict = false) +public class BookDetailsToRead { + + @Element(name = "title") + public String title; + + @Element(name = "image_url") + public String image_url; + + @Element(name = "small_image_url") + public String small_image_url; + + @Element(name = "authors") + public Authors authors; + + @Element(name = "average_rating") + public float rating; + + @Element(name = "ratings_count") + public String ratingCount; + + public float getRating() { + return rating; + } + + public String getRatingCount() { + return ratingCount; + } + + + public String getTitle() { + return title; + } + + public String getImage_url() { + return image_url; + } + + public String getSmall_image_url() { + return small_image_url; + } + + public Authors getAuthor() { + return authors; + } + + +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse.java new file mode 100644 index 0000000..0494576 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse.java @@ -0,0 +1,22 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "GoodreadsResponse", strict = false) +public class GoodreadsResponse { + + + @Element(name = "search") + public Search search; + + public Search getSearch() { + return search; + } + + public GoodreadsResponse() { + + } + + +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse2.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse2.java new file mode 100644 index 0000000..8ef0a3c --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse2.java @@ -0,0 +1,23 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "GoodreadsResponse", strict = false) +public class GoodreadsResponse2 { + + + @Element(name = "book") + public BookDescription bDesc; + + public BookDescription getbDesc() { + return bDesc; + } + + public GoodreadsResponse2() { + + } + + +} + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse3.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse3.java new file mode 100644 index 0000000..fac5618 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/GoodreadsResponse3.java @@ -0,0 +1,30 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import java.util.List; + +@Root(name = "GoodreadsResponse", strict = false) +public class GoodreadsResponse3 { + + + @ElementList(name = "books") + public List bookDetailsToReads; + +// public ToReadModel getToReadModelReviews() { +// return toReadModelReviews; +// } + + + public List getBookDetailsToReads() { + return bookDetailsToReads; + } + + public GoodreadsResponse3() { + + } + + +} + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/Book.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/Book.java new file mode 100644 index 0000000..54a8bf7 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/Book.java @@ -0,0 +1,80 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks; + +import com.google.gson.annotations.SerializedName; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; + +import java.util.List; + +import io.realm.RealmList; +import io.realm.RealmObject; + +public class Book extends RealmObject { + + @SerializedName("id") + String id; + @SerializedName("detail") + String detail; + @SerializedName("title") + String title; + @SerializedName("author") + String author; + @SerializedName("rating") + float rating; + @SerializedName("ratings_count") + Long ratingsCount; + @SerializedName("gr_id") + String grId; + @SerializedName("gr_img_url") + String grImgUrl; + @SerializedName("email") + String email; + @SerializedName("owner") + RealmList userInfoList; + @SerializedName("description") + String description; + + public String getAuthor() { + return author; + } + + public String getEmail() { + return email; + } + + public String getGrId() { + return grId; + } + + public String getGrImgUrl() { + return grImgUrl; + } + + public String getId() { + return id; + } + + public String getDetail() { + return detail; + } + + public float getRating() { + return rating; + } + + public Long getRatingsCount() { + return ratingsCount; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + + public List getUserInfoList() { + return userInfoList; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookAddDeleteResponse.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookAddDeleteResponse.java new file mode 100644 index 0000000..a9fb429 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookAddDeleteResponse.java @@ -0,0 +1,46 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks; + +import com.google.gson.annotations.SerializedName; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; + +import java.util.List; + +/** + * Created by harshit on 17/1/18. + */ + +public class BookAddDeleteResponse { + + @SerializedName("detail") + String detail; + + @SerializedName("cancels") + List cancelList; + + @SerializedName("userInfoList") + List userList; + + public String getDetail() { + return detail; + } + + public void setDetail(String detail) { + this.detail = detail; + } + + public List getCancelList() { + return cancelList; + } + + public void setCancelList(List cancelList) { + this.cancelList = cancelList; + } + + public List getUserList() { + return userList; + } + + public void setUserList(List userList) { + this.userList = userList; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookDetailWithCancel.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookDetailWithCancel.java new file mode 100644 index 0000000..421156b --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookDetailWithCancel.java @@ -0,0 +1,35 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks; + +import com.google.gson.annotations.SerializedName; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; + +import java.util.List; + +public class BookDetailWithCancel { + + + @SerializedName("book") + Book book; + @SerializedName("userInfoList") + List userInfoList; + @SerializedName("cancels") + List cancels; + + public List getCancels() { + return cancels; + } + + int count; + + public int getCount() { + return count; + } + + public Book getBook() { + return book; + } + + public List getUserInfoList(){ + return userInfoList; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookList.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookList.java new file mode 100644 index 0000000..1668920 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/BookList.java @@ -0,0 +1,28 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + + +public class BookList { + + @SerializedName("results") + List results; + @SerializedName("cancels") + List cancels; + + public List getCancels() { + return cancels; + } + + int count; + + public int getCount() { + return count; + } + + public List getResults() { + return results; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/RemoveBook.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/RemoveBook.java new file mode 100644 index 0000000..3f2837f --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalBooks/RemoveBook.java @@ -0,0 +1,28 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks; + +import com.google.gson.annotations.SerializedName; + +public class RemoveBook { + + @SerializedName("user_id") + String userId; + + @SerializedName("book_id") + String bookId; + + public String getBookId() { + return bookId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public void setBookId(String bookId) { + this.bookId = bookId; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalUsers/UserDetailWithCancel.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalUsers/UserDetailWithCancel.java new file mode 100644 index 0000000..625a6b1 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalUsers/UserDetailWithCancel.java @@ -0,0 +1,22 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class UserDetailWithCancel { + + @SerializedName("user_info") + UserInfo userInfo; + + @SerializedName("cancels") + List cancels; + + public List getCancels() { + return cancels; + } + + public UserInfo getUserInfo() { + return userInfo; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalUsers/UserInfo.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalUsers/UserInfo.java new file mode 100644 index 0000000..fb43dcb --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/LocalUsers/UserInfo.java @@ -0,0 +1,139 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers; + +import com.google.gson.annotations.SerializedName; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; + +import java.util.List; + +import io.realm.RealmList; +import io.realm.RealmObject; + +public class UserInfo extends RealmObject { + + @SerializedName("id") + String id; + @SerializedName("email") + String email; + @SerializedName("college") + String college; + @SerializedName("hostel") + String hostel; + @SerializedName("enr_no") + String enrNo; + @SerializedName("room_no") + String roomNo; + @SerializedName("first_name") + String firstName; + @SerializedName("last_name") + String lastName; + @SerializedName("contact_no") + String contactNo; + @SerializedName("image_url") + String imageUrl; + + public String getFcm_id() { + return fcm_id; + } + + public void setFcm_id(String fcm_id) { + this.fcm_id = fcm_id; + } + + @SerializedName("fcm_id") + String fcm_id; + + @SerializedName("books") + RealmList userBookList; + + public String getEmail() { + return email; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public String getName() { + return firstName + " " + lastName; + } + + public String getRoomNo() { + return roomNo; + } + + public String getId() { + return id; + } + + public String getHostel() { + return hostel; + } + + public List getUserBookList() { + return userBookList; + } + + public String getCollege() { + return college; + } + + public String getContactNo() { + return contactNo; + } + + public String getEnrNo() { + return enrNo; + } + + public void setCollege(String college) { + this.college = college; + } + + public void setContactNo(String contactNo) { + this.contactNo = contactNo; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setEnrNo(String enrNo) { + this.enrNo = enrNo; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public void setHostel(String hostel) { + this.hostel = hostel; + } + + public void setId(String id) { + this.id = id; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public void setRoomNo(String roomNo) { + this.roomNo = roomNo; + } + + public void setUserBookList(RealmList userBookList) { + this.userBookList = userBookList; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Login.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Login.java new file mode 100644 index 0000000..06b5943 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Login.java @@ -0,0 +1,29 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import com.google.gson.annotations.SerializedName; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; + +public class Login { + + @SerializedName("token") + String token; + + @SerializedName("userInfo") + UserInfo userInfo; + + @SerializedName("detail") + String detail; + + public String getToken() { + return token; + } + + public UserInfo getUserInfo() { + return userInfo; + } + + public String getDetail() { + return detail; + } + +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Notification/Notification_Model.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Notification/Notification_Model.java new file mode 100644 index 0000000..8586e3c --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Notification/Notification_Model.java @@ -0,0 +1,46 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.Notification; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * Created by ajayrahul on 9/6/16. + */ +public class Notification_Model { + + @SerializedName("count") + String count; + + @SerializedName("next") + String next; + + @SerializedName("previous") + String previous; + + @SerializedName("page") + String page; + + public String getPage() { + return page; + } + + @SerializedName("results") + List notificationsList; + + public String getPrevious() { + return previous; + } + + public String getNext() { + return next; + } + + public List getNotificationsList() { + return notificationsList; + } + + public String getCount() { + return count; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Notification/Notifications.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Notification/Notifications.java new file mode 100644 index 0000000..4162d7f --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Notification/Notifications.java @@ -0,0 +1,82 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.Notification; + +import com.google.gson.annotations.SerializedName; + +/** + * Created by ajayrahul on 9/6/16. + */ +public class Notifications { + + @SerializedName("id") + String id; + + @SerializedName("detail") + String detail; + + @SerializedName("sender_id") + String senderId; + + @SerializedName("sender_name") + String senderName; + + @SerializedName("book_id") + String bookId; + + @SerializedName("book_title") + String bookTitle; + + @SerializedName("message") + String message; + + @SerializedName("is_confirmed") + boolean isConfirmed; + + @SerializedName("is_owner") + String isOwner; + + @SerializedName("is_cancelled") + boolean isCancelled; + + @SerializedName("unix_time") + long unix_time; + + public long getUnix_time() { + return unix_time; + } + + public String getDetail() { + return detail; + } + + public String getId() { + return id; + } + + public String getSenderId() { + return senderId; + } + + public String getSenderName() { + return senderName; + } + + public String getBookId() { + return bookId; + } + + public String getBookTitle() { + return bookTitle; + } + + public String getMessage() { + return message; + } + + public boolean getIsConfirmed() { + return isConfirmed; + } + + public boolean getIsCancelled() { + return isCancelled; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Search.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Search.java new file mode 100644 index 0000000..4f0738c --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Search.java @@ -0,0 +1,27 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import java.util.List; + +@Root(name = "search", strict = false) +public class Search { + @Element(name = "source") + String source; + + @ElementList(name = "results") + List books; + + public String getSource() { + return source; + } + + public List getBooks() { + return books; + } + + +} + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Signup.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Signup.java new file mode 100644 index 0000000..2d4c0e3 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/Signup.java @@ -0,0 +1,13 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import com.google.gson.annotations.SerializedName; + +public class Signup { + + @SerializedName("detail") + private String detail; + + public String getDetail() { + return detail; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/ToReadModel.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/ToReadModel.java new file mode 100644 index 0000000..90ac397 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/ToReadModel.java @@ -0,0 +1,21 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +import java.util.List; + +@Root(name = "books", strict = false) +public class ToReadModel { + + @Element(name = "book") + List bookDetailsToReadsList; + + public List getBookDetailList() { + return bookDetailsToReadsList; + } +} + + + + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/UserImageResult.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/UserImageResult.java new file mode 100644 index 0000000..8ec7002 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/UserImageResult.java @@ -0,0 +1,32 @@ +package com.sdsmdg.bookshareapp.BSA.api.models; + +import com.google.gson.annotations.SerializedName; + +/** + * Created by harshit on 30/10/17. + */ + +public class UserImageResult { + + @SerializedName("detail") + private String detail; + + @SerializedName("image_url") + private String imageUrl; + + public String getDetail() { + return detail; + } + + public void setDetail(String detail) { + this.detail = detail; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/VerifyToken/Detail.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/VerifyToken/Detail.java new file mode 100644 index 0000000..b3fc3b2 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/api/models/VerifyToken/Detail.java @@ -0,0 +1,13 @@ +package com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken; + +import com.google.gson.annotations.SerializedName; + +public class Detail { + + @SerializedName("detail") + String detail; + + public String getDetail() { + return detail; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/firebase_classes/FirebaseInstanceIDService.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/firebase_classes/FirebaseInstanceIDService.java new file mode 100644 index 0000000..020a528 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/firebase_classes/FirebaseInstanceIDService.java @@ -0,0 +1,57 @@ +package com.sdsmdg.bookshareapp.BSA.firebase_classes; + +import android.widget.Toast; + +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.iid.FirebaseInstanceIdService; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + + +public class FirebaseInstanceIDService extends FirebaseInstanceIdService { + private static final String TAG = "MyFirebaseInsIDService"; + String token = Helper.getToken(); + String id = Helper.getId(); + + + @Override + public void onTokenRefresh() { + String refreshedToken = FirebaseInstanceId.getInstance().getToken(); + //Log.d(TAG, "New Token : " + refreshedToken); + //save token in ur server. + + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = usersAPI.update_fcm_id( + token, + refreshedToken + ); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + if (response.body().getDetail().equals("FCM_ID changed")) { + //Toast.makeText(getApplicationContext(), "FCM_ID changed", Toast.LENGTH_SHORT).show(); + } else { + //Toast.makeText(getApplicationContext(), "Request not valid", Toast.LENGTH_SHORT).show(); + } + } else { + //Log.i("CPA", "request body is null"); + } + } + + @Override + public void onFailure(Call call, Throwable t) { +// Toast.makeText(getApplicationContext(), R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + + + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/firebase_classes/MyFirebaseMessagingService.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/firebase_classes/MyFirebaseMessagingService.java new file mode 100644 index 0000000..b03af32 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/firebase_classes/MyFirebaseMessagingService.java @@ -0,0 +1,112 @@ +package com.sdsmdg.bookshareapp.BSA.firebase_classes; + +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.media.RingtoneManager; +import android.net.Uri; +import android.support.v4.app.NotificationCompat; +import android.util.Log; + +import com.google.firebase.messaging.RemoteMessage; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.ui.MainActivity; + +import java.util.ArrayList; + + +/** + * Created by ajayrahul on 1/12/16. + */ +public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService { + + private static final String TAG = "MyFirebaseMsgService"; + public static ArrayList notifications = new ArrayList<>(); + PendingIntent pendingIntent; + final static String GROUP_KEY = "fcm_notifs"; + int size = 0; + public int no_notifs = 0; + + + @Override + public void onDestroy() { + super.onDestroy(); + } + + @Override + public void onCreate() { + super.onCreate(); + } + + @Override + public void onMessageReceived(RemoteMessage remoteMessage) { + + //check for notifs.. + if (remoteMessage.getNotification() != null) { + Log.d(TAG, "Message data : " + remoteMessage.getNotification().getBody()); + String title = remoteMessage.getNotification().getTitle(); + String message = remoteMessage.getNotification().getBody(); + sendNotification(title,message); + return; + } + + + //check if msg contains data.. + if (remoteMessage.getData().size() > 0) { + String name = remoteMessage.getData().get("name"); + String body = remoteMessage.getData().get("body"); + String book = remoteMessage.getData().get("book"); + String title = remoteMessage.getData().get("title"); + String message = name + " " + body + " " + book; + sendNotification(title, message); + } + + + } + + + private void sendNotification(String title, String body) { + + Log.i("Reached here ", "inside send ----->"); + + Intent intent = new Intent(this, MainActivity.class); + intent.putExtra("data", "open"); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + + pendingIntent = PendingIntent.getActivity(this, 0 /*request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + //setting sound : + Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + NotificationCompat.Builder notificationBuilder; + notificationBuilder = new NotificationCompat.Builder(this) + .setSmallIcon(R.mipmap.logo1) + .setAutoCancel(true) + .setSound(notificationSound) + .setContentIntent(pendingIntent); + + NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); + + if (notifications.size() == 0) { + notificationBuilder.setContentTitle(title) + .setContentText(body); + } else { + size = notifications.size() + 1; + notificationBuilder.setContentTitle(title); + inboxStyle.setBigContentTitle("You have " + size + " Notifications."); + } + + + notifications.add(body); + for (int i = 0; i < notifications.size(); i++) { + inboxStyle.addLine(notifications.get(i)); + } + + notificationBuilder.setStyle(inboxStyle); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(0, notificationBuilder.build()); + + } + + +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/BookDetailsActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/BookDetailsActivity.java new file mode 100644 index 0000000..dfee335 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/BookDetailsActivity.java @@ -0,0 +1,389 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.v4.content.ContextCompat; +import android.support.v4.widget.NestedScrollView; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.customtabs.CustomTabsIntent; +import android.text.TextUtils; +import android.transition.TransitionManager; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.RatingBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookAddDeleteResponse; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookDetailWithCancel; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.RemoveBook; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.Local.UsersAdapter; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; +import com.squareup.picasso.Picasso; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; + +import jp.wasabeef.blurry.Blurry; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class BookDetailsActivity extends AppCompatActivity { + + public static final String TAG = BookDetailsActivity.class.getSimpleName(); + + Book book; + String title, author, gr_id, gr_img_url, description, rating_count; + Long ratingsCount; + Float rating; + public TextView authorBook; + TextView bookTitle, bookDescription; + public RatingBar ratingBook; + public TextView ratingCount; + List userInfoList; + UsersAdapter usersAdapter; + String bookId, bookTitleText; + ImageView image; + public static String Response; + FrameLayout rootView; + NestedScrollView scrollView; + Boolean showMore = false; + CustomProgressDialog customProgressDialog; + Button addToMyLibraryButton, removeFromMyLibraryButton; + String token, userId; + SharedPreferences prefs; + + //for chrome custom tabs + CustomTabsIntent customTabsIntent; + CustomTabsIntent.Builder intentBuilder; + + public static String getResponse() { + return Response; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_books_details); + prefs = getSharedPreferences("Token", MODE_PRIVATE); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + customProgressDialog = new CustomProgressDialog(BookDetailsActivity.this); + customProgressDialog.setCancelable(false); + customProgressDialog.show(); + token = prefs.getString("token", null); + userId = prefs.getString("id", ""); + addToMyLibraryButton = (Button) findViewById(R.id.add_to_my_library); + removeFromMyLibraryButton = (Button) findViewById(R.id.remove_from_my_library); + authorBook = (TextView) findViewById(R.id.book_author); + ratingBook = (RatingBar) findViewById(R.id.book_rating); + ratingCount = (TextView) findViewById(R.id.ratings_count); + image = (ImageView) findViewById(R.id.book_image); + bookTitle = (TextView) findViewById(R.id.book_title); + bookDescription = (TextView) findViewById(R.id.description); + rootView = (FrameLayout) findViewById(R.id.root_view); + scrollView = (NestedScrollView) findViewById(R.id.scroll_view); + bookDescription.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showMore = !showMore; + + if (showMore) { + bookDescription.setMaxLines(50); + bookDescription.setEllipsize(null); + } else { + bookDescription.setMaxLines(4); + bookDescription.setEllipsize(TextUtils.TruncateAt.END); + } + } + }); + + SharedPreferences prefs = getSharedPreferences("Token", MODE_PRIVATE); + + String id = getIntent().getExtras().getString("id"); + String idd = prefs.getString("id", ""); + + + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + + + OkHttpClient.Builder httpclient = new OkHttpClient.Builder().addInterceptor(interceptor); + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(CommonUtilities.local_books_api_url) + .addConverterFactory(GsonConverterFactory.create()) + .client(httpclient.build()) + .build(); + + UsersAPI api = retrofit.create(UsersAPI.class); + + Call call = api.getBookDetails(id,id, "Token " + prefs + .getString("token", null)); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.body() != null && response.body().getBook().getDetail() == null) { + book = response.body().getBook(); + Response = response.toString(); + Helper.setBookId(book.getId()); + Helper.setBookTitle(book.getTitle()); + bookId = book.getId(); + gr_id = book.getId(); + bookTitleText = book.getTitle(); + bookTitle.setText(book.getTitle()); + title = book.getTitle(); + //This stores whether the request sent by the user is cancelled or not + List cancels = response.body().getCancels(); + if (book.getDescription().trim() == "") { + bookDescription.setText("No Description Available"); + } else { + bookDescription.setText(book.getDescription()); + } + description = book.getDescription(); + + authorBook.setText("by " + book.getAuthor()); + author = book.getAuthor(); + DecimalFormat formatter = new DecimalFormat("##,##,###"); + rating_count = formatter.format(book.getRatingsCount()); + + ratingCount.setText("(" + rating_count + ")"); + ratingsCount = book.getRatingsCount(); + ratingBook.setRating(book.getRating()); + rating = book.getRating(); + Picasso.with(BookDetailsActivity.this).load(book.getGrImgUrl()).into(image); + Blurry.with(BookDetailsActivity.this) + .radius(25) + .sampling(1) + .color(Color.argb(66, 0, 0, 0)) + .async() + .capture(findViewById(R.id.book_image)) + .into((ImageView) findViewById(R.id.book_image)); + gr_img_url = book.getGrImgUrl(); + List userTempInfoList = response.body().getUserInfoList(); + checkIfOwner(userTempInfoList); + userInfoList.clear(); + userInfoList.addAll(userTempInfoList); + usersAdapter.setCancels(cancels); + usersAdapter.setBookId(book.getId()); + usersAdapter.setBookTitle(book.getTitle()); + usersAdapter.notifyDataSetChanged(); + } else { + Toast.makeText(getApplicationContext(), "Book not found", Toast.LENGTH_SHORT).show(); + } + TransitionManager.beginDelayedTransition(rootView); + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + + customProgressDialog.dismiss(); + } + }, 1000); + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + TransitionManager.beginDelayedTransition(rootView); + customProgressDialog.dismiss(); + Toast.makeText(BookDetailsActivity.this, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + finish(); + + + } + }); + RecyclerView usersList = (RecyclerView) findViewById(R.id.reader_list); + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); + usersList.setLayoutManager(layoutManager); + userInfoList = new ArrayList<>(); + usersAdapter = new UsersAdapter(true, idd, this, userInfoList, bookTitleText, bookId, new UsersAdapter.OnItemClickListener() { + @Override + public void onItemClick(UserInfo userInfo) { + } + }); + usersList.setAdapter(usersAdapter); + + + + //regarding chrome custom tab + // Initialize intentBuilder + intentBuilder = new CustomTabsIntent.Builder(); + + // Set toolbar(tab) color of your chrome browser + intentBuilder.setToolbarColor(ContextCompat.getColor(this, R.color.colorPrimary)); + + // Define entry and exit animation + intentBuilder.setExitAnimations(this, R.anim.right_to_left_end, R.anim.left_to_right_end); + intentBuilder.setStartAnimations(this, R.anim.left_to_right_start, R.anim.right_to_left_start); + intentBuilder.setSecondaryToolbarColor(ContextCompat.getColor(this, R.color.colorPrimary)); + + // build it by setting up all + customTabsIntent = intentBuilder.build(); + + } + + public void checkIfOwner(List userInfoList) { + for (UserInfo item : userInfoList) { + if (item.getId().equals(Helper.getUserId())) { + addToMyLibraryButton.setVisibility(View.GONE); + removeFromMyLibraryButton.setVisibility(View.VISIBLE); + + } + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return (true); + } + + return (super.onOptionsItemSelected(item)); + } + + public void addToMyLibraryClicked(final View view) { + ((Button)view).setText("Adding..."); + view.setEnabled(false); + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call addBookCall = usersAPI.addBook(Helper.getUserEmail(), title, author, gr_id, ratingsCount, rating, gr_img_url, description, "Token " + token); + addBookCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + //getDetail() returns whether the book has been added or not + ((Button)view).setText("Add to My Library"); + view.setEnabled(true); + if (response.body() != null) { + String detail = response.body().getDetail(); + Toast.makeText(BookDetailsActivity.this, detail, Toast.LENGTH_SHORT).show(); + if (detail.equals("Book Added")) { + view.animate() + .translationY(-view.getHeight()) + .alpha(0.0f) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + view.setVisibility(View.GONE); + view.setAlpha(1.0f); + view.setTranslationY(0); + removeFromMyLibraryButton.setVisibility(View.VISIBLE); + } + }); + userInfoList.clear(); + usersAdapter.setCancels(response.body().getCancelList()); + userInfoList.addAll(response.body().getUserList()); + usersAdapter.notifyDataSetChanged(); + } + } else { + Toast.makeText(BookDetailsActivity.this, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + ((Button)view).setText("Add to My Library"); + view.setEnabled(true); + Toast.makeText(BookDetailsActivity.this, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + + public void goodreads(View view) { + + // go to website goodreads + customTabsIntent.launchUrl(this, Uri.parse("http://www.goodreads.com/work/best_book/"+bookId)); + } + + public void removeFromMyLibraryClicked(View view) { + removeBook(view, bookId); + } + + private void removeBook(final View view, final String bookId) { + + ((Button)view).setText("Removing..."); + view.setEnabled(false); + RemoveBook removeBook = new RemoveBook(); + removeBook.setBookId(bookId); + removeBook.setUserId(userId); + + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = usersAPI.removeBook(removeBook, "Token " + prefs.getString("token", null)); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + ((Button)view).setText("Remove from My Library"); + view.setEnabled(true); + if (response.body() != null) { + String detail = response.body().getDetail(); + Toast.makeText(BookDetailsActivity.this, detail, Toast.LENGTH_SHORT).show(); + if (detail.equals("Successfully Removed!!")){ + if (response.body().getUserList().size() == 0){ + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + finish(); + } + }, 500); + }else { + view.animate() + .translationY(-view.getHeight()) + .alpha(0.0f) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + view.setVisibility(View.GONE); + view.setAlpha(1.0f); + view.setTranslationY(0); + addToMyLibraryButton.setVisibility(View.VISIBLE); + } + }); + userInfoList.clear(); + usersAdapter.setCancels(response.body().getCancelList()); + userInfoList.addAll(response.body().getUserList()); + usersAdapter.notifyDataSetChanged(); + } + } + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + ((Button)view).setText("Remove from My Library"); + view.setEnabled(true); + Toast.makeText(BookDetailsActivity.this, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } +} + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/ChangePasswordActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/ChangePasswordActivity.java new file mode 100644 index 0000000..9f7dc76 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/ChangePasswordActivity.java @@ -0,0 +1,149 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Handler; +import android.support.design.widget.TextInputEditText; +import android.support.design.widget.TextInputLayout; +import android.support.v7.app.AppCompatActivity; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class ChangePasswordActivity extends AppCompatActivity { + + String token; + SharedPreferences prefs; + private TextInputLayout oldPasswordInputLayout, newPasswordInputLayout; + private TextInputEditText oldPasswordEditText, newPasswordEditText; + private Button submitButton; + private CustomProgressDialog progressDialog; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_change_password); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + prefs = getSharedPreferences("Token", MODE_PRIVATE); + token = prefs.getString("token", null); + + initViews(); + regListeners(); + } + + private void regListeners() { + submitButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (oldPasswordEditText.getText().length() < 6) { + oldPasswordInputLayout.setErrorEnabled(true); + newPasswordInputLayout.setErrorEnabled(false); + oldPasswordInputLayout.setError("The password must be of atleast 6 characters"); + } else if (newPasswordEditText.getText().length() < 6) { + oldPasswordInputLayout.setErrorEnabled(false); + newPasswordInputLayout.setErrorEnabled(true); + newPasswordInputLayout.setError("The password must be of atleast 6 characters"); + } else { + oldPasswordInputLayout.setEnabled(false); + newPasswordInputLayout.setEnabled(false); + View focusable = getCurrentFocus(); + if (focusable != null) { + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(focusable.getWindowToken(), 0); + } + onSaveClicked(); + } + } + }); + } + + private void initViews() { + oldPasswordInputLayout = (TextInputLayout) findViewById(R.id.old_password_edit_text_layout); + newPasswordInputLayout = (TextInputLayout) findViewById(R.id.new_password_edit_text_layout); + oldPasswordEditText = (TextInputEditText) findViewById(R.id.old_pwd_edit_text); + newPasswordEditText = (TextInputEditText) findViewById(R.id.new_pwd_edit_text); + submitButton = (Button) findViewById(R.id.save); + progressDialog = new CustomProgressDialog(this); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + + return (super.onOptionsItemSelected(item)); + } + + public void onSaveClicked() { + progressDialog.show(); + + String oldPassword = oldPasswordEditText.getText().toString(); + String newPassword = newPasswordEditText.getText().toString(); + + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = usersAPI.changePassword( + "Token " + token, + oldPassword, + newPassword + ); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + progressDialog.dismiss(); + if (response.body() != null) { + if (response.body().getDetail().equals("Password changed")) { + Toast.makeText(ChangePasswordActivity.this, + "Password changed", Toast.LENGTH_SHORT).show(); + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + finish(); + } + }, 500); + } + //The request is not valid when the password provided by the user is not correct + else { + oldPasswordInputLayout.setEnabled(true); + newPasswordInputLayout.setEnabled(true); + Toast.makeText(ChangePasswordActivity.this, + "The password entered is incorrect!!", Toast.LENGTH_SHORT).show(); + } + } else { + oldPasswordInputLayout.setEnabled(true); + newPasswordInputLayout.setEnabled(true); + Toast.makeText(ChangePasswordActivity.this, + R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + oldPasswordInputLayout.setEnabled(true); + newPasswordInputLayout.setEnabled(true); + progressDialog.dismiss(); + Toast.makeText(ChangePasswordActivity.this, + R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/College.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/College.java new file mode 100644 index 0000000..b11f587 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/College.java @@ -0,0 +1,34 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +/** + * Created by Harshit Bansal on 5/16/2017. + */ + +public class College { + + private String collegeName; + private String collegeDomain; + + public College(){}; + + public College(String collegeName, String collegeDomain) { + this.collegeName = collegeName; + this.collegeDomain = collegeDomain; + } + + public String getCollegeDomain() { + return collegeDomain; + } + + public void setCollegeDomain(String collegeDomain) { + this.collegeDomain = collegeDomain; + } + + public String getCollegeName() { + return collegeName; + } + + public void setCollegeName(String collegeName) { + this.collegeName = collegeName; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/CustomProgressDialog.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/CustomProgressDialog.java new file mode 100644 index 0000000..13c781a --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/CustomProgressDialog.java @@ -0,0 +1,33 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.app.ProgressDialog; +import android.content.Context; +import android.os.Bundle; + +import com.sdsmdg.bookshareapp.BSA.R; + +public class CustomProgressDialog extends ProgressDialog { + public CustomProgressDialog(Context context) { + super(context); + } + + @Override + public void dismiss() { + super.dismiss(); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.custom_progressdialog2); + + //TODO:Fix the lottie animation +// LottieAnimationView animationView = (LottieAnimationView) findViewById(R.id.animation_view); +// animationView.setImageAssetsFolder("images"); +// animationView.setAnimation("PinJump.json", LottieAnimationView.CacheStrategy.Strong); +// animationView.playAnimation(); +// animationView.loop(true); + + + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/EditProfileActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/EditProfileActivity.java new file mode 100644 index 0000000..6c0cd4f --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/EditProfileActivity.java @@ -0,0 +1,177 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.NavUtils; +import android.support.v7.app.AppCompatActivity; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class EditProfileActivity extends AppCompatActivity { + + EditText firstName, lastName, contactNo, roomNo; + Spinner hostelSpinner; + String id, email; + SharedPreferences preferences, hostelPref; + String hostel; + UserInfo userInfo; + CustomProgressDialog progressDialog; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_edit_profile); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + firstName = (EditText) findViewById(R.id.first_name); + lastName = (EditText) findViewById(R.id.last_name); + contactNo = (EditText) findViewById(R.id.contact_no); + roomNo = (EditText) findViewById(R.id.room_no); + hostelSpinner = (Spinner) findViewById(R.id.hostel_spinner); + + preferences = getSharedPreferences("Token", MODE_PRIVATE); + + hostelPref = getSharedPreferences("hostel_res_id", MODE_PRIVATE); + int hostelResId = hostelPref.getInt("hostel_id", R.array.iitr_hostel_list); + + id = preferences.getString("id", null); + email = preferences.getString("email", null); + firstName.setText(preferences.getString("first_name", null)); + lastName.setText(preferences.getString("last_name", null)); + contactNo.setText(preferences.getString("contact_no", null)); + roomNo.setText(preferences.getString("room_no", null)); + hostel = preferences.getString("hostel", null); + + ArrayAdapter adapter = ArrayAdapter.createFromResource(this, hostelResId, android.R.layout.simple_spinner_item); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + hostelSpinner.setAdapter(adapter); + if (!hostel.equals(null)) { + int spinnerPosition = adapter.getPosition(hostel); + hostelSpinner.setSelection(spinnerPosition); + } + + hostelSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + hostel = parent.getItemAtPosition(position).toString(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + + } + + private void saveClicked() { + + progressDialog = new CustomProgressDialog(EditProfileActivity.this); + progressDialog.setCancelable(false); + progressDialog.show(); + + userInfo = new UserInfo(); + userInfo.setFirstName(firstName.getText().toString()); + userInfo.setLastName(lastName.getText().toString()); + userInfo.setRoomNo(roomNo.getText().toString()); + userInfo.setContactNo(contactNo.getText().toString()); + userInfo.setHostel(hostel); + + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = usersAPI.editUserDetails( + "Token " + preferences.getString("token", null), + preferences.getString("id", null), + userInfo + ); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + progressDialog.dismiss(); + if (response.body() != null) { + SharedPreferences.Editor editor = preferences.edit(); + editor.putString("first_name", firstName.getText().toString()); + editor.putString("last_name", lastName.getText().toString()); + editor.putString("room_no", roomNo.getText().toString()); + editor.putString("hostel", hostel); + editor.apply(); + Helper.setUserName(firstName.getText().toString() + " " + lastName.getText().toString()); + if (response.body().getDetail().equals("A verification code has been sent")){ + Intent verifyOtpIntent = new Intent + (EditProfileActivity.this, VerifyOtpActivity.class); + verifyOtpIntent.putExtra("contact", contactNo.getText().toString()); + verifyOtpIntent.putExtra("email", email); + startActivity(verifyOtpIntent); + finish(); + }else if (response.body().getDetail().equals("The profile has been updated")){ + editor.putString("contact_no", contactNo.getText().toString()); + editor.apply(); + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + finish(); + } + }, 1000); + } + } else { + Toast.makeText(EditProfileActivity.this, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + t.printStackTrace(); + progressDialog.dismiss(); + Toast.makeText(getApplicationContext(), R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_edit_profile, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.save_details){ + View focused = getCurrentFocus(); + if (focused != null) { + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(focused.getWindowToken(), 0); + } + saveClicked(); + } + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/GRLoginActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/GRLoginActivity.java new file mode 100644 index 0000000..f1c295a --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/GRLoginActivity.java @@ -0,0 +1,315 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.http.SslError; +import android.os.Build; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.webkit.CookieManager; +import android.webkit.CookieSyncManager; +import android.webkit.SslErrorHandler; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.Button; +import android.widget.TextView; + +import com.google.api.client.auth.oauth.OAuthAuthorizeTemporaryTokenUrl; +import com.google.api.client.auth.oauth.OAuthCredentialsResponse; +import com.google.api.client.auth.oauth.OAuthGetAccessToken; +import com.google.api.client.auth.oauth.OAuthGetTemporaryToken; +import com.google.api.client.auth.oauth.OAuthHmacSigner; +import com.google.api.client.auth.oauth.OAuthParameters; +import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.HttpRequestFactory; +import com.google.api.client.http.HttpResponse; +import com.google.api.client.http.apache.ApacheHttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + + +public class GRLoginActivity extends AppCompatActivity { + + Button login; + TextView textView; + //url tags + public static final String BASE_GOODREADS_URL = "https://www.goodreads.com"; + public static final String TOKEN_SERVER_URL = BASE_GOODREADS_URL + "/oauth/request_token"; + public static final String AUTHENTICATE_URL = BASE_GOODREADS_URL + "/oauth/authorize?mobile=1"; + public static final String ACCESS_TOKEN_URL = BASE_GOODREADS_URL + "/oauth/access_token"; + + public static final String GOODREADS_KEY = CommonUtilities.API_KEY; + public static final String GOODREADS_SECRET = CommonUtilities.SECRET; + public static String authUrl; + + OAuthHmacSigner signer; + OAuthGetTemporaryToken getTemporaryToken; + OAuthCredentialsResponse temporaryTokenResponse; + OAuthAuthorizeTemporaryTokenUrl accessTempToken; + SharedPreferences pref; + CustomProgressDialog progressDialog; + WebView webView; + boolean success = true; + Thread thread; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_grlogin); + + progressDialog = new CustomProgressDialog(this); + login = (Button) findViewById(R.id.gr_login); + textView = (TextView) findViewById(R.id.info_text); + pref = getApplicationContext().getSharedPreferences("UserId", MODE_PRIVATE); + webView = (WebView) findViewById(R.id.webview); + webView.setWebViewClient(new WebViewClient() { + + @Override + public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) { + final AlertDialog.Builder builder = new AlertDialog.Builder(GRLoginActivity.this); + builder.setMessage("Continue without SSL certificate?"); + builder.setPositiveButton("Proceed", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + handler.proceed(); + } + }); + builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + handler.cancel(); + } + }); + final AlertDialog dialog = builder.create(); + dialog.show(); + } + }); + /** webview settings */ + webView.getSettings().setJavaScriptEnabled(true); + webView.getSettings().setLoadWithOverviewMode(true); + webView.getSettings().setUseWideViewPort(true); + webView.clearCache(true); + clearCookies(webView.getContext()); + + + //Here we are generating a temporary token + signer = new OAuthHmacSigner(); + // Get Temporary Token + getTemporaryToken = new OAuthGetTemporaryToken(TOKEN_SERVER_URL); + signer.clientSharedSecret = GOODREADS_SECRET; + getTemporaryToken.signer = signer; + getTemporaryToken.consumerKey = GOODREADS_KEY; + getTemporaryToken.transport = new NetHttpTransport(); + + + /**Everything is inside this thread, + the webview is updated using runOnUiThread + */ + thread = new Thread() { + @Override + public void run() { + try { + temporaryTokenResponse = getTemporaryToken.execute(); + accessTempToken = new OAuthAuthorizeTemporaryTokenUrl(AUTHENTICATE_URL); + accessTempToken.temporaryToken = temporaryTokenResponse.token; + authUrl = accessTempToken.build(); + System.out.println("Goodreads oAuth sample: Please visit the following URL to authorize:"); + + /**this is the authentication url*/ + System.out.println(authUrl); + GRLoginActivity.this.runOnUiThread(new Runnable() { + @Override + public void run() { + //opening it on webview, if its already authenticated..will open homepage..else sign in page of GR + progressDialog.dismiss(); + webView.loadUrl(authUrl); + } + }); + + /** we are obtaining the access token ...*/ + + OAuthGetAccessToken getAccessToken = new OAuthGetAccessToken(ACCESS_TOKEN_URL); + + getAccessToken.signer = signer; + + signer.tokenSharedSecret = temporaryTokenResponse.tokenSecret; + getAccessToken.temporaryToken = temporaryTokenResponse.token; + getAccessToken.transport = new NetHttpTransport(); + getAccessToken.consumerKey = GOODREADS_KEY; + if (Thread.interrupted()) { + throw new InterruptedException(); + } + + OAuthCredentialsResponse accessTokenResponse = null; + final Long start = System.currentTimeMillis(); + Long s; + while (true) { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + + s = System.currentTimeMillis() - start; + /**if at all timer is required + // we've put up a timeout of s seconds.. + */ + try { + accessTokenResponse = getAccessToken.execute(); + if (!accessTokenResponse.toString().contains("Invalid OAuth Request")) { + break; + } + } catch (IOException e) { + } + } + + if (accessTokenResponse == null) { + success = false; + throw new IOException("nill"); + } + + OAuthParameters oauthParameters = new OAuthParameters(); + signer.tokenSharedSecret = accessTokenResponse.tokenSecret; + + oauthParameters.signer = signer; + oauthParameters.consumerKey = GOODREADS_KEY; + oauthParameters.token = accessTokenResponse.token; + System.out.println(accessTokenResponse.token + " and " + accessTokenResponse.tokenSecret); + Helper.setAccessToken(accessTokenResponse.token); + Helper.setAccessSecret(accessTokenResponse.tokenSecret); + + HttpRequestFactory requestFactory = new ApacheHttpTransport().createRequestFactory(oauthParameters); + GenericUrl genericUrl = new GenericUrl("https://www.goodreads.com/api/auth_user"); + HttpResponse resp = requestFactory.buildGetRequest(genericUrl).execute(); + + //for extracting the id from the xml http response.. + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + InputSource is; + try { + builder = factory.newDocumentBuilder(); + is = new InputSource(new StringReader(resp.parseAsString())); + Document doc = builder.parse(is); + XPathFactory xPathfactory = XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression expr = xpath.compile("//GoodreadsResponse/user[@id]"); + NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); + + for (int x = 0; x < nl.getLength(); x++) { + Node currentItem = nl.item(x); + String key = currentItem.getAttributes().getNamedItem("id").getNodeValue(); + System.out.println(key); + SharedPreferences.Editor editor = pref.edit(); + editor.putString("userGrId", key); + editor.apply(); + Helper.setUserGRid(key); + } + + } catch (ParserConfigurationException p) { + + } catch (SAXException sa) { + + } catch (XPathExpressionException x) { + + } + + } catch (IOException e) { + e.printStackTrace(); + if (e.toString() == "nill") { + success = false; + Intent i = new Intent(GRLoginActivity.this, GRLoginActivity.class); + startActivity(i); + finish(); + } + } catch (InterruptedException i) { + Intent inn = new Intent(GRLoginActivity.this, MainActivity.class); + startActivity(inn); + finish(); + + } finally { + SharedPreferences preff = getSharedPreferences("UserId", MODE_PRIVATE); + + if (success && preff.getString("userGrId", null) != null) { + Intent intent = new Intent(GRLoginActivity.this, ToReadActivity.class); + startActivity(intent); + finish(); + } else if (preff.getString("userGrId", null) == null) { + Intent intent = new Intent(GRLoginActivity.this, MainActivity.class); + startActivity(intent); + finish(); + } + } + } + }; + + login.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + login.setVisibility(View.GONE); + textView.setVisibility(View.GONE); + progressDialog.setCancelable(false); + progressDialog.show(); + thread.start(); + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + + + } + + @Override + public void onBackPressed() { + thread.interrupt(); + finish(); + super.onBackPressed(); + + } + + + @SuppressWarnings("deprecation") + public static void clearCookies(Context context) { + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + Log.d("Cookie", "Using clearCookies code for API >=" + String.valueOf(Build.VERSION_CODES.LOLLIPOP_MR1)); + CookieManager.getInstance().removeAllCookies(null); + CookieManager.getInstance().flush(); + } else { + Log.d("Cookie", "Using clearCookies code for API <" + String.valueOf(Build.VERSION_CODES.LOLLIPOP_MR1)); + CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(context); + cookieSyncMngr.startSync(); + CookieManager cookieManager = CookieManager.getInstance(); + cookieManager.removeAllCookie(); + cookieManager.removeSessionCookie(); + cookieSyncMngr.stopSync(); + cookieSyncMngr.sync(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/GuestActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/GuestActivity.java new file mode 100644 index 0000000..0922231 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/GuestActivity.java @@ -0,0 +1,136 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.support.design.widget.Snackbar; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.FrameLayout; + +import com.sdsmdg.bookshareapp.BSA.Listeners.EndlessScrollListener; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookList; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.Local.BooksAdapterSimple; + +import java.util.ArrayList; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class GuestActivity extends AppCompatActivity { + + final String TAG = GuestActivity.class.getSimpleName(); + + FrameLayout rootView; + RecyclerView localBookList; + List booksList = new ArrayList<>(); + BooksAdapterSimple adapter; + SwipeRefreshLayout refreshLayout; + LinearLayoutManager layoutManager; + View.OnClickListener signupclicklistener; + CustomProgressDialog customProgressDialog; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_guest); + customProgressDialog = new CustomProgressDialog(GuestActivity.this); + customProgressDialog.setCancelable(false); + customProgressDialog.show(); + + rootView = (FrameLayout) findViewById(R.id.root_view); + + adapter = new BooksAdapterSimple(this, booksList, new BooksAdapterSimple.OnItemClickListener() { + @Override + public void onItemClick(Book book) { + Snackbar snbar = Snackbar.make(findViewById(R.id.frameLayout), "Create a new account ! ", Snackbar.LENGTH_SHORT) + .setAction("Sign Up", signupclicklistener); + snbar.setActionTextColor(getResources().getColor(R.color.colorAccent)); + snbar.show(); + snbar.show(); + + } + }); + + signupclicklistener = new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent i = new Intent(GuestActivity.this, SignupActivity.class); + startActivity(i); + } + }; + + layoutManager = new LinearLayoutManager(this); + localBookList = (RecyclerView) findViewById(R.id.local_books_list); + localBookList.setLayoutManager(layoutManager); + localBookList.setAdapter(adapter); + + final EndlessScrollListener endlessScrollListener = new EndlessScrollListener((LinearLayoutManager) layoutManager) { + @Override + public void onLoadMore(int page, int totalItemsCount) { + getLocalBooks(String.valueOf(page + 1)); + } + }; + + localBookList.addOnScrollListener(endlessScrollListener); + + refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_to_refresh_layout); + refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + endlessScrollListener.reset(); + getLocalBooks("1"); + } + + }); + + getLocalBooks("1"); + } + + public void getLocalBooks(final String page) { + UsersAPI api = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = api.getGuestBList(page); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + List localBooksList = response.body().getResults(); + if (page.equals("1")) { + booksList.clear(); + adapter.notifyDataSetChanged(); + } + booksList.addAll(localBooksList); + adapter.notifyDataSetChanged(); + refreshLayout.setRefreshing(false); + } + + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + customProgressDialog.dismiss(); + } + }, 1000); + + } + + @Override + public void onFailure(Call call, Throwable t) { + refreshLayout.setRefreshing(false); + customProgressDialog.dismiss(); + + } + }); + + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/LoginActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/LoginActivity.java new file mode 100644 index 0000000..e1fcb58 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/LoginActivity.java @@ -0,0 +1,324 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Paint; +import android.net.Uri; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.text.InputType; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; +import com.sdsmdg.bookshareapp.BSA.api.models.Login; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; + +import butterknife.ButterKnife; +import butterknife.InjectView; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class LoginActivity extends AppCompatActivity { + private static final String TAG = "LoginActivity"; + private static final int REQUEST_SIGNUP = 0; + SharedPreferences pref, prevEmail;//The prevEmail preference is used to store the last two email of the user for the suggestion + + @InjectView(R.id.input_email) + AutoCompleteTextView _emailText; + @InjectView(R.id.input_password) + EditText _passwordText; + @InjectView(R.id._btn_show_password) + ImageButton _showPassword; + @InjectView(R.id.btn_login) + Button _loginButton; + @InjectView(R.id.link_signup) + TextView _signupLink; + @InjectView(R.id.link_forgot_password) + TextView forgotPasswordLink; + @InjectView(R.id.new_activation) + TextView newActivation; + @InjectView(R.id.new_otp) + TextView newOtp; + String token; + Context context; + boolean showPassword = false; + CustomProgressDialog customProgressDialog; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + + ButterKnife.inject(this); + + context = this; + // underline the forget password and new activation text view + forgotPasswordLink.setPaintFlags(forgotPasswordLink.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); + newActivation.setPaintFlags(newActivation.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); + newOtp.setPaintFlags(newActivation.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); + + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(_emailText.getWindowToken(), 0); + + if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_VIEW)){ + if (getIntent().getData() != null){ + checkActivation(getIntent().getData()); + } + } + pref = getApplicationContext().getSharedPreferences("Token", MODE_PRIVATE); + prevEmail = getApplicationContext().getSharedPreferences("Previous Email", MODE_PRIVATE); + String emails[]; + if (prevEmail.getString("email1", null) == null) { + emails = new String[1]; + emails[0] = prevEmail.getString("email2", null); + } else if (prevEmail.getString("email2", null) == null) { + emails = new String[1]; + emails[0] = prevEmail.getString("email1", null); + } else { + emails = new String[2]; + emails[0] = prevEmail.getString("email1", null); + emails[1] = prevEmail.getString("email2", null); + } + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_dropdown_item_1line, emails); + _emailText.setAdapter(adapter); + + token = pref.getString("token", ""); + _showPassword.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!showPassword) { + _passwordText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); + showPassword = true; + _passwordText.setSelection(_passwordText.getText().length()); + _showPassword.setImageResource(R.drawable.ic_visible_on); + } else { + _passwordText.setInputType(129); //input type = password + showPassword = false; + _passwordText.setSelection(_passwordText.getText().length()); + _showPassword.setImageResource(R.drawable.ic_visible_off); + } + } + + }); + + _loginButton.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(v.getWindowToken(), 0); + login(); + } + }); + + _signupLink.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + // Start the Signup activity + Intent intent = new Intent(getApplicationContext(), SignupActivity.class); + startActivity(intent); + } + }); + + forgotPasswordLink.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(getApplicationContext(), SendEmailActivity.class); + intent.putExtra("email_type", "forgot_password_email"); + startActivity(intent); + } + }); + + newActivation.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(getApplicationContext(), SendEmailActivity.class); + intent.putExtra("email_type", "new_activation_email"); + startActivity(intent); + } + }); + + newOtp.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(getApplicationContext(), SendEmailActivity.class); + intent.putExtra("email_type", "new_otp"); + startActivity(intent); + } + }); + } + + private void checkActivation(Uri data) { + final CustomProgressDialog progressDialog = new CustomProgressDialog(this); + progressDialog.show(); + String[] segments = data.getPath().split("/"); + UsersAPI usersApi = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call checkActivationCall = usersApi.checkActivation( + segments[2]); + checkActivationCall.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + progressDialog.dismiss(); + if (response.body().getDetail() != null){ + Toast.makeText(LoginActivity.this, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + } else{ + Toast.makeText(LoginActivity.this, "Please Try Again!", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + progressDialog.dismiss(); + t.printStackTrace(); + Toast.makeText(LoginActivity.this, "Please Try Again!", Toast.LENGTH_SHORT).show(); + } + }); + } + + public void guestModeClicked(View view) { + Intent i = new Intent(this, GuestActivity.class); + startActivity(i); + } + + public void signUpClicked(View view) { + Intent i = new Intent(this, SignupActivity.class); + startActivity(i); + } + + public void login() { + if (!validate()) { + onLoginFailed("Fill complete details!"); + return; + } + + //_loginButton.setEnabled(false); + + customProgressDialog = new CustomProgressDialog(LoginActivity.this); + customProgressDialog.setCancelable(false); + customProgressDialog.show(); + + String email = _emailText.getText().toString(); + String password = _passwordText.getText().toString(); + Helper.setUserEmail(email); + + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = usersAPI.getToken(email, password); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + if (response.body().getDetail() != null) { + onLoginFailed(response.body().getDetail()); + } + if (response.body().getToken() != null) { + setNewEmail(_emailText.getText().toString());//This function sets the new entered email into the shared prefs for suggestions + onLoginSuccess(); + saveinSP(response.body().getToken(), response.body().getUserInfo()); + } + } + customProgressDialog.dismiss(); + } + @Override + public void onFailure(Call call, Throwable t) { + onLoginFailed("Check your network connectivity and try again!"); + t.printStackTrace(); + customProgressDialog.dismiss(); + } + }); + } + + public void setNewEmail(String email) { + + String email2 = prevEmail.getString("email2", null); + + String email1 = email2; + if (!email.equals(email1)) { + email2 = email; + } else { + email2 = null; + } + + SharedPreferences.Editor editor = prevEmail.edit(); + editor.putString("email1", email1); + editor.putString("email2", email2); + editor.apply(); + } + + @Override + public void onBackPressed() { + // disable going back to the MainActivity + moveTaskToBack(true); + } + + public void onLoginSuccess() { + _loginButton.setEnabled(true); + Intent i = new Intent(this, MainActivity.class); + i.putExtra("data_login", "update"); + startActivity(i); + finish(); + } + + public void onLoginFailed(String message) { + Toast.makeText(getBaseContext(), message, Toast.LENGTH_LONG).show(); + + _loginButton.setEnabled(true); + } + + public boolean validate() { + boolean valid = true; + + String email = _emailText.getText().toString(); + String password = _passwordText.getText().toString(); + + if (email.isEmpty()) { + _emailText.setError("enter a valid email address"); + valid = false; + } else { + _emailText.setError(null); + } + + if (password.isEmpty() || password.length() < 6 || password.length() > 15) { + _passwordText.setError("between 6 and 15 alphanumeric characters"); + valid = false; + } else { + _passwordText.setError(null); + } + + return valid; + } + + private void saveinSP(String token, UserInfo userInfo) { + + pref = getSharedPreferences("Token", MODE_PRIVATE); + + SharedPreferences.Editor editor = pref.edit(); + editor.putString("token", token); + editor.putString("id", userInfo.getId()); + editor.putString("email", userInfo.getEmail()); + editor.putString("first_name", userInfo.getFirstName()); + editor.putString("last_name", userInfo.getLastName()); + editor.putString("hostel", userInfo.getHostel()); + editor.putString("room_no", userInfo.getRoomNo()); + editor.putString("contact_no", userInfo.getContactNo()); + editor.putString("enr_no", userInfo.getEnrNo()); + editor.putString("college", userInfo.getCollege()); + editor.apply(); + + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/MainActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/MainActivity.java new file mode 100644 index 0000000..1936f12 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/MainActivity.java @@ -0,0 +1,794 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.support.design.widget.NavigationView; +import android.support.design.widget.Snackbar; +import android.support.v4.view.GravityCompat; +import android.support.v4.view.MenuItemCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SearchView; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.firebase.iid.FirebaseInstanceId; +import com.jakewharton.picasso.OkHttp3Downloader; +import com.sdsmdg.bookshareapp.BSA.Listeners.EndlessScrollListener; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookList; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.firebase_classes.MyFirebaseMessagingService; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.Local.BooksAdapterSimple; +import com.sdsmdg.bookshareapp.BSA.ui.fragments.NotificationFragment; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; +import com.sdsmdg.bookshareapp.BSA.utils.RxSearchViewObservable; +import com.squareup.picasso.Picasso; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import io.reactivex.functions.Predicate; +import io.reactivex.schedulers.Schedulers; +import io.realm.Realm; +import io.realm.RealmConfiguration; +import io.realm.RealmResults; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + + +public class MainActivity extends AppCompatActivity implements + NavigationView.OnNavigationItemSelectedListener, NotificationFragment.OnFragmentInteractionListener{ + + public static final String TAG = MainActivity.class.getSimpleName(); + private static final int REQUEST_CODE = 1000; + private static final int BOOK_DETAIL_REQUEST_CODE = 1001; + private boolean isrightDrawerOpen = false; + + List booksList; + BooksAdapterSimple adapter; + SharedPreferences prefs, notificationSharedPreferences; + SwipeRefreshLayout refreshLayout; + SearchView searchView; + String Resp; + + //Creates a list of visible snackbars + List visibleSnackbars = new ArrayList<>(); + DrawerLayout drawerLayout; + NavigationView navigationView; + RecyclerView localBooksList; + Toolbar toolbar; + int backCounter = 0; + ImageView _profilePicture; + NotificationFragment notifFragment; + Boolean progress_isVisible = false; + //Search Menu item reference in the toolbar + MenuItem searchItem; + TextView noBookstextview; + ProgressBar progressBar; + //toReadName for to-read search + String toReadName = null; + TextView notifCountTextView; + //Create a realm object to handle our local database + Realm realm; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Create a new empty instance of Realm + realm = Realm.getDefaultInstance(); + + // Use the Sentry DSN (client key) from the Project Settings page on Sentry + //Sentry.init(CommonUtilities.SENTRY_DSN, new AndroidSentryClientFactory(ctx)); + + //customProgressDialog = new CustomProgressDialog(MainActivity.this); + //customProgressDialog.setCancelable(false); + prefs = getSharedPreferences("Token", MODE_PRIVATE); + + Helper.setUserId(prefs.getString("id", prefs.getString("id", ""))); + Helper.setUserName(prefs.getString("first_name", null) + " " + prefs.getString("last_name", null)); + + Helper.setId(prefs.getString("id", null)); + Helper.setToken(prefs.getString("token", null)); + + SharedPreferences preferences = getSharedPreferences("Token", MODE_PRIVATE); + notificationSharedPreferences = getSharedPreferences("notif_count", MODE_PRIVATE); + + setContentView(R.layout.activity_main); + noBookstextview = (TextView) findViewById(R.id.no_books_textView); + progressBar = (ProgressBar) findViewById(R.id.indeterminateBar); + noBookstextview.setVisibility(View.GONE); + progress_isVisible = false; + + notifFragment = (NotificationFragment) getSupportFragmentManager().findFragmentById(R.id.right_drawer); + drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); + + if (getIntent().getExtras() != null) { + + toReadName = getIntent().getExtras().getString("toReadName"); + if (toReadName != null) { + if (toReadName.equals("open")) { + notifFragment.getNotifications("1"); + MyFirebaseMessagingService.notifications.clear(); + drawerLayout.openDrawer(GravityCompat.END); + } + } + + + toReadName = getIntent().getExtras().getString("data_splash"); + if (toReadName != null && toReadName.equals("open_drawer")) { + notifFragment.getNotifications("1"); + MyFirebaseMessagingService.notifications.clear(); + drawerLayout.openDrawer(GravityCompat.END); + } + + toReadName = getIntent().getExtras().getString("data_login"); + if (toReadName != null && toReadName.equals("update")) { + + String token = "Token " + preferences.getString("token", null); + + String refreshedToken = FirebaseInstanceId.getInstance().getToken(); + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call2 = usersAPI.update_fcm_id( + token, + refreshedToken + ); + call2.enqueue(new Callback() { + @Override + public void onResponse(Call call2, Response response) { + if (response.body() != null) { + if (response.body().getDetail().equals("FCM_ID changed")) { + //FCM Id was changed successfully + } else { +// Toast.makeText(getApplicationContext(), R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + } else { + //The FCM ID didn't change + } + removeAnyVisibleSnackbars(); + } + + @Override + public void onFailure(Call call, Throwable t) { + Snackbar.make(findViewById(R.id.coordinatorlayout), "You are offline", Snackbar.LENGTH_INDEFINITE).setCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar snackbar, int event) { + visibleSnackbars.remove(snackbar); + super.onDismissed(snackbar, event); + } + + @Override + public void onShown(Snackbar snackbar) { + visibleSnackbars.add(snackbar); + super.onShown(snackbar); + } + }).setAction("RETRY", new View.OnClickListener() { + @Override + public void onClick(View view) { + refresh(); + } + }).show(); + } + }); + + + } + + } + localBooksList = (RecyclerView) findViewById(R.id.localBooksList); + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); + localBooksList.setLayoutManager(layoutManager); + + //Show what's available offline first + RealmResults realmBooksList = realm.where(Book.class).findAll(); + booksList = realm.copyFromRealm(realmBooksList); + + adapter = new BooksAdapterSimple(this, booksList, new BooksAdapterSimple.OnItemClickListener() { + @Override + public void onItemClick(Book book) { + + if (isOnline()) { + Intent intent = new Intent(MainActivity.this, BookDetailsActivity.class); + intent.putExtra("id", book.getId()); + startActivityForResult(intent, BOOK_DETAIL_REQUEST_CODE); + } else { + Toast.makeText(MainActivity.this, "Please check your internet connection!!", Toast.LENGTH_SHORT).show(); + } + + } + }); + localBooksList.setAdapter(adapter); + + getLocalBooks("1"); + + final EndlessScrollListener endlessScrollListener = new EndlessScrollListener((LinearLayoutManager) layoutManager) { + @Override + public void onLoadMore(int page, int totalItemsCount) { + getLocalBooks(String.valueOf(page + 1)); + } + }; + + localBooksList.addOnScrollListener(endlessScrollListener); + navigationView = (NavigationView) findViewById(R.id.left_drawer); + navigationView.setNavigationItemSelectedListener(this); + + View header = navigationView.getHeaderView(0); + TextView _name = (TextView) header.findViewById(R.id.nav_name); + TextView _email = (TextView) header.findViewById(R.id.nav_email); + final ImageView _profilePicture = (ImageView) header.findViewById(R.id.nav_profile_picture); + this._profilePicture = _profilePicture; + + Picasso.Builder builder = new Picasso.Builder(MainActivity.this); + builder.downloader(new OkHttp3Downloader(getOkHttpClient())).build() + .load(CommonUtilities.currentUserImageUrl) + .placeholder(R.drawable.ic_profile_pic) + .into(_profilePicture); + + Helper.imageChanged = false; + _profilePicture.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent profileIntent = new Intent(MainActivity.this, MyProfile.class); + startActivity(profileIntent); + } + }); + + if (_name != null) { + _name.setText(preferences.getString("first_name", "") + " " + preferences.getString("last_name", "")); + } + + if (_email != null) { + _email.setText(Helper.getUserEmail()); + } + + toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar.setTitleTextColor(getResources().getColor(R.color.White)); + setSupportActionBar(toolbar); + + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) { + @Override + public void onDrawerClosed(View drawerView) { + super.onDrawerClosed(drawerView); + if (isrightDrawerOpen) { + isrightDrawerOpen = false; + notifCountTextView.setVisibility(View.GONE); + } + } + + @Override + public void onDrawerOpened(View drawerView) { + super.onDrawerOpened(drawerView); + if (drawerLayout.isDrawerOpen(GravityCompat.END)) { + isrightDrawerOpen = true; + notifFragment.getNotifications("1"); + } + } + }; + drawerLayout.setDrawerListener(toggle); + + toggle.syncState(); + + refreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh_layout); + refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + endlessScrollListener.reset(); + getLocalBooks("1"); + } + + }); + + //When a to read book is to be checked if it exists in campus + toReadName = getIntent().getStringExtra("pass_it_on"); + } + + public void searchClicked(View view) { + Intent i = new Intent(this, SearchResultsActivity.class); + startActivityForResult(i, REQUEST_CODE); + } + + private void showProgressBar() { + progressBar.setVisibility(View.VISIBLE); + noBookstextview.setVisibility(View.GONE); + localBooksList.setVisibility(View.GONE); + } + + private void hideProgressBar() { + progressBar.setVisibility(View.GONE); + } + + private Observable> dataFromNetwork(final String query) { + UsersAPI api = NetworkingFactory.getLocalInstance().getUsersAPI(); + return api.search + (query, "Token " + prefs.getString("token", null)) + .subscribeOn(Schedulers.io()); + } + + private void showResults(List bookList) { + booksList.clear(); + booksList.addAll(bookList); + refreshLayout.setRefreshing(false); + if (bookList.size() == 0){ + noBookstextview.setVisibility(View.VISIBLE); + localBooksList.setVisibility(View.GONE); + }else{ + noBookstextview.setVisibility(View.GONE); + localBooksList.setVisibility(View.VISIBLE); + } + adapter.notifyDataSetChanged(); + } + + /** + * When an item in the toolbar is clicked, the following + * method is called. + **/ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_main, menu); + final MenuItem notifItem = menu.findItem(R.id.menu_notifs); + searchItem = menu.findItem(R.id.search); + MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(MenuItem item) { + refreshLayout.setEnabled(false); + notifItem.setVisible(false); + return true; + } + + @Override + public boolean onMenuItemActionCollapse(MenuItem item) { + notifItem.setVisible(true); + getLocalBooks("1"); + localBooksList.setVisibility(View.VISIBLE); + noBookstextview.setVisibility(View.GONE); + refreshLayout.setEnabled(true); + refreshLayout.setRefreshing(true); + return true; + } + }); + searchView = (SearchView) MenuItemCompat.getActionView(searchItem); + regRxObservable(); + + //If toReadName received from to-read is not null, search it first + if (toReadName != null) { + searchItem.expandActionView(); + searchView.requestFocus(); + searchView.setQuery(toReadName, true); + } + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + + MenuItem item = menu.findItem(R.id.menu_notifs); + RelativeLayout notifRelativeLayout = (RelativeLayout) MenuItemCompat.getActionView(item); + notifCountTextView = (TextView) notifRelativeLayout.findViewById(R.id.notif_count); + notifRelativeLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Helper.setOld_total(Helper.getNew_total()); + if (drawerLayout.isDrawerOpen(GravityCompat.END)) { + drawerLayout.closeDrawer(GravityCompat.END); + + } else { + drawerLayout.closeDrawer(GravityCompat.START); + drawerLayout.openDrawer(GravityCompat.END); + } + } + }); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + if (id == R.id.menu_notifs) { + + notifFragment.getNotifications("1"); + Helper.setOld_total(Helper.getNew_total()); + if (drawerLayout.isDrawerOpen(GravityCompat.END)) { + drawerLayout.closeDrawer(GravityCompat.END); + + } else { + drawerLayout.closeDrawer(GravityCompat.START); + drawerLayout.openDrawer(GravityCompat.END); + } + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onNavigationItemSelected(MenuItem item) { + int id = item.getItemId(); + + if (id == R.id.nav_myprofile) { + Intent i = new Intent(this, MyProfile.class); + startActivityForResult(i, BOOK_DETAIL_REQUEST_CODE); + + } else if (id == R.id.nav_grlogin) { + SharedPreferences preff = getSharedPreferences("UserId", MODE_PRIVATE); + if (preff.getString("userGrId", null) == null) { + Intent in = new Intent(this, GRLoginActivity.class); + startActivity(in); + } else { + Intent i = new Intent(this, ToReadActivity.class); + startActivity(i); + } + } else if (id == R.id.nav_logout) { + final SharedPreferences prefs = getSharedPreferences("Token", MODE_PRIVATE); + String token = "Token " + prefs.getString("token", null); + + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call2 = usersAPI.logout( + token, + "none" + ); + call2.enqueue(new Callback() { + @Override + public void onResponse(@android.support.annotation.NonNull Call call2, + Response response) { + removeAnyVisibleSnackbars(); + SharedPreferences.Editor editor = prefs.edit(); + editor.clear(); + editor.apply(); + Intent i = new Intent(MainActivity.this, LoginActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(i); + finish(); + } + + @Override + public void onFailure(Call call, Throwable t) { + Snackbar.make(findViewById(R.id.coordinatorlayout), R.string.you_are_offline, Snackbar.LENGTH_INDEFINITE).setCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar snackbar, int event) { + visibleSnackbars.remove(snackbar); + super.onDismissed(snackbar, event); + } + + @Override + public void onShown(Snackbar snackbar) { + visibleSnackbars.add(snackbar); + super.onShown(snackbar); + } + }).setAction("RETRY", new View.OnClickListener() { + @Override + public void onClick(View view) { + refresh(); + } + }).show(); + } + }); + + } else if (id == R.id.nav_share) { + + Intent waIntent = new Intent(Intent.ACTION_SEND); + waIntent.setType("text/plain"); + waIntent.putExtra(Intent.EXTRA_SUBJECT, "Citadel"); + String text = "Citadel App !! .You can download the app from here...!"; + waIntent.putExtra(Intent.EXTRA_TEXT, text); + startActivity(Intent.createChooser(waIntent, "Share with")); + + } else if (id == R.id.nav_usersearch) { + Intent i = new Intent(this, UserSearchActivity.class); + startActivity(i); + } + + drawerLayout.closeDrawer(GravityCompat.START); + + return true; + } + + public void getLocalBooks(final String page) { + UsersAPI api = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = api.getLocalBList(page, "Token " + prefs.getString("token", null)); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + Resp = response.toString(); + List localBookList = response.body().getResults(); + if (page.equals("1")) { + + adapter.setTotalCount(response.body().getCount()); + + //Save the first page to the offline database + realm.beginTransaction(); + //Remove all previously stored books + realm.deleteAll(); + realm.copyToRealmOrUpdate(localBookList); + realm.commitTransaction(); + + booksList.clear(); + adapter.notifyDataSetChanged(); + + removeAnyVisibleSnackbars(); + } + booksList.addAll(localBookList); + if (booksList.size() == 0){ + localBooksList.setVisibility(View.GONE); + noBookstextview.setVisibility(View.VISIBLE); + }else{ + localBooksList.setVisibility(View.VISIBLE); + noBookstextview.setVisibility(View.GONE); + } + adapter.notifyDataSetChanged(); + refreshLayout.setRefreshing(false); + } else { + Resp = "null"; + } + + } + + @Override + public void onFailure(Call call, Throwable t) { + Snackbar.make(findViewById(R.id.coordinatorlayout), R.string.you_are_offline, Snackbar.LENGTH_INDEFINITE).setCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar snackbar, int event) { + visibleSnackbars.remove(snackbar); + super.onDismissed(snackbar, event); + } + + @Override + public void onShown(Snackbar snackbar) { + visibleSnackbars.add(snackbar); + super.onShown(snackbar); + } + }).setAction("RETRY", new View.OnClickListener() { + @Override + public void onClick(View view) { + refresh(); + } + }).show(); + refreshLayout.setRefreshing(false); + } + }); + + } + + private void regRxObservable() { + RxSearchViewObservable.fromView(searchView) + .debounce(300, TimeUnit.MILLISECONDS) + .filter(new Predicate() { + @Override + public boolean test(String text) throws Exception { + if (text.isEmpty()) { + return false; + } else { + return true; + } + } + }) + .distinctUntilChanged() + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(new Consumer() { + @Override + public void accept(String s) throws Exception { + showProgressBar(); + } + }) + .switchMap(new Function>>() { + @Override + public ObservableSource> apply(String query) throws Exception { + return dataFromNetwork(query); + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer>() { + @Override + public void accept(List userInfos) throws Exception { + hideProgressBar(); + showResults(userInfos); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + hideProgressBar(); + Snackbar.make(findViewById(R.id.coordinatorlayout), "You are offline", Snackbar.LENGTH_INDEFINITE).setCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar snackbar, int event) { + visibleSnackbars.remove(snackbar); + super.onDismissed(snackbar, event); + } + + @Override + public void onShown(Snackbar snackbar) { + visibleSnackbars.add(snackbar); + super.onShown(snackbar); + } + }).setAction("RETRY", new View.OnClickListener() { + @Override + public void onClick(View view) { + refresh(); + } + }).show(); + refreshLayout.setRefreshing(false); + } + }); + } + + @Override + public void onFragmentInteraction(Uri uri) { + } + + public boolean isOnline() { + ConnectivityManager cm = + (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo netInfo = cm.getActiveNetworkInfo(); + return netInfo != null && netInfo.isConnectedOrConnecting(); + } + + @Override + public void onBackPressed() { + + if (this.drawerLayout.isDrawerVisible(GravityCompat.START)) { + this.drawerLayout.closeDrawer(GravityCompat.START); + } if (this.drawerLayout.isDrawerVisible(GravityCompat.END)){ + this.drawerLayout.closeDrawer(GravityCompat.END); + } else{ + if (!progress_isVisible) { + + if (backCounter >= 1) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + + } else { + + Snackbar.make(findViewById(R.id.coordinatorlayout), "Press Again To Exit", Snackbar.LENGTH_LONG).setCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar snackbar, int event) { + super.onDismissed(snackbar, event); + visibleSnackbars.remove(snackbar); + /* + This callback is required because if "Press Again To Exit" Snackbar + comes in offline mode, the "You are offline" Snackbar should appear + again, if user choses not to close the app + */ + if (!isOnline()) { + Snackbar.make(findViewById(R.id.coordinatorlayout), "You are offline", Snackbar.LENGTH_INDEFINITE).setCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar snackbar, int event) { + super.onDismissed(snackbar, event); + visibleSnackbars.remove(snackbar); + } + + @Override + public void onShown(Snackbar snackbar) { + super.onShown(snackbar); + visibleSnackbars.add(snackbar); + } + }).setAction("RETRY", new View.OnClickListener() { + @Override + public void onClick(View view) { + refresh(); + } + }).show(); + } + } + + @Override + public void onShown(Snackbar snackbar) { + super.onShown(snackbar); + visibleSnackbars.add(snackbar); + } + }).show(); + + backCounter++; + new Handler().postDelayed(new Runnable() { + + @Override + public void run() { + backCounter = 0; + } + }, 2000); + + } + } + } + + } + + private OkHttpClient getOkHttpClient() { + OkHttpClient client = new OkHttpClient.Builder() + .addInterceptor(new Interceptor() { + @Override + public okhttp3.Response intercept(Chain chain) throws IOException { + Request newRequest = chain.request().newBuilder() + .addHeader("Authorization", "Token " + prefs + .getString("token", null)) + .build(); + return chain.proceed(newRequest); + } + }).build(); + return client; + } + + @Override + protected void onResume() { + super.onResume(); + if (Helper.imageChanged) { + new Picasso.Builder(MainActivity.this). + downloader(new OkHttp3Downloader(getOkHttpClient())).build() + .load(CommonUtilities.currentUserImageUrl).into(_profilePicture); + Helper.imageChanged = false; + } + navigationView.setCheckedItem(R.id.menu_none);//This will check a invisible item, effectively unselecting all items + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == REQUEST_CODE || requestCode == BOOK_DETAIL_REQUEST_CODE) { + getLocalBooks("1"); + } + } + + @Override + protected void onPause() { + super.onPause(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + realm.close(); + } + + private void removeAnyVisibleSnackbars() { + if (visibleSnackbars.size() != 0) { + visibleSnackbars.get(0).dismiss(); + visibleSnackbars.clear(); + } + } + + @Override + protected void onStart() { + super.onStart(); + } + + private void refresh() { + getLocalBooks("1"); + } +} + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/MyProfile.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/MyProfile.java new file mode 100644 index 0000000..db44b19 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/MyProfile.java @@ -0,0 +1,524 @@ + +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +import android.support.design.widget.FloatingActionButton; +import android.support.v4.widget.NestedScrollView; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.jakewharton.picasso.OkHttp3Downloader; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserDetailWithCancel; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; +import com.sdsmdg.bookshareapp.BSA.api.models.UserImageResult; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.Local.BookAdapter; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.FileUtils; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; +import com.sdsmdg.bookshareapp.BSA.utils.PermissionUtils; +import com.sdsmdg.bookshareapp.BSA.utils.SPDataLoader; +import com.squareup.picasso.MemoryPolicy; +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import de.hdodenhof.circleimageview.CircleImageView; +import id.zelory.compressor.Compressor; +import jp.wasabeef.blurry.Blurry; +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + + +public class MyProfile extends AppCompatActivity { + + final String TAG = MyProfile.class.getSimpleName(); + private static final int SEARCH_RESULTS_REQUEST_CODE = 1001; + + TextView userName, userEmail, address, titleBooksCount; + UserInfo user; + String id; + String url = CommonUtilities.local_books_api_url + "image/" + Helper.getUserId() + "/"; + String imageUrl; + int REQUEST_CAMERA = 0, SELECT_FILE = 1; + String userChoosenTask; + CircleImageView profilePicture; + ImageView backgroundImageView; + NestedScrollView scrollView; + SPDataLoader loader = new SPDataLoader(); + SharedPreferences prefs; + List booksList; + BookAdapter adapter; + RecyclerView mRecyclerView; + String Resp; + FloatingActionButton button; + TextView noItemsTextView; + ProgressBar bookProgressBar; + + private int noOfBooks = 0; + private String token; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setTitle("My Profile"); + setContentView(R.layout.activity_my_profile); + + prefs = getApplicationContext().getSharedPreferences("Token", Context.MODE_PRIVATE); + + bookProgressBar = (ProgressBar) findViewById(R.id.book_progress_bar); + noItemsTextView = (TextView) findViewById(R.id.no_items_text); + mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); + titleBooksCount = (TextView) findViewById(R.id.title_books_count); + + SharedPreferences preferences = getSharedPreferences("Token", MODE_PRIVATE); + token = preferences.getString("token", null); + id = preferences.getString("id", ""); + + setUpRecyclerView(id); + + getUserInfoDetails(id); + getProfilePicture(null); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + profilePicture = (CircleImageView) findViewById(R.id.profile_picture); + userName = (TextView) findViewById(R.id.user_name); + userEmail = (TextView) findViewById(R.id.user_email); + address = (TextView) findViewById(R.id.address); + backgroundImageView = (ImageView) findViewById(R.id.background_image); + scrollView = (NestedScrollView) findViewById(R.id.scroll); + scrollView.setSmoothScrollingEnabled(true); + mRecyclerView.setNestedScrollingEnabled(false); + + button = (FloatingActionButton) findViewById(R.id.button); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent i = new Intent(MyProfile.this, SearchResultsActivity.class); + startActivityForResult(i, SEARCH_RESULTS_REQUEST_CODE); + } + }); + } + + + //This function is called from BookAdapter, when a book is sucessfully removed + public void onBookRemoved() { + noOfBooks -= 1; + Log.i(TAG, "onBookRemoved: 1"); + titleBooksCount.setText("Books" + "(" + String.valueOf(noOfBooks) + ")"); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.my_profile_menu, menu); + return true; + } + + public void getUserInfoDetails(String id) { + + bookProgressBar.setVisibility(View.VISIBLE); + noItemsTextView.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.GONE); + UsersAPI api = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = api.getUserDetails(id, id, "Token " + prefs + .getString("token", null)); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + bookProgressBar.setVisibility(View.GONE); + if (response.body() != null) { + Resp = response.toString(); + user = response.body().getUserInfo(); + List booksTempInfoList = user.getUserBookList(); + if (booksTempInfoList.size() == 0) { + noItemsTextView.setVisibility(View.VISIBLE); + mRecyclerView.setVisibility(View.GONE); + }else{ + noItemsTextView.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + } + booksList.clear(); + booksList.addAll(booksTempInfoList); + noOfBooks = booksList.size(); + titleBooksCount.setText("Books" + "(" + noOfBooks + ")"); + adapter.notifyDataSetChanged(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + bookProgressBar.setVisibility(View.GONE); + } + }); + } + + private void getProfilePicture(final String detail) { + new Picasso.Builder(MyProfile.this). + downloader(new OkHttp3Downloader(getOkHttpClient())).build() + .load(CommonUtilities.currentUserImageUrl) + .memoryPolicy(MemoryPolicy.NO_CACHE) + .into(new Target() { + @Override + public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { + if (detail != null) { + Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show(); + } + profilePicture.setImageBitmap(bitmap); + backgroundImageView.setImageBitmap(bitmap); + Blurry.with(getApplicationContext()) + .radius(40) + .sampling(1) + .color(Color.argb(66, 0, 0, 0)) + .async() + .capture(findViewById(R.id.background_image)) + .into((ImageView) findViewById(R.id.background_image)); + } + + @Override + public void onBitmapFailed(Drawable errorDrawable) { + profilePicture.setImageResource(R.drawable.user_default_image); + backgroundImageView.setImageResource(R.drawable.user_default_image); + Blurry.with(getApplicationContext()) + .radius(40) + .sampling(1) + .color(Color.argb(66, 0, 0, 0)) + .async() + .capture(findViewById(R.id.background_image)) + .into((ImageView) findViewById(R.id.background_image)); + } + + @Override + public void onPrepareLoad(Drawable placeHolderDrawable) { + } + }); + } + + private OkHttpClient getOkHttpClient() { + OkHttpClient client = new OkHttpClient.Builder() + .addInterceptor(new Interceptor() { + @Override + public okhttp3.Response intercept(@NonNull Chain chain) throws IOException { + Request newRequest = chain.request().newBuilder() + .addHeader("Authorization", "Token " + prefs + .getString("token", null)) + .build(); + return chain.proceed(newRequest); + } + }).build(); + return client; + } + + private void setUpRecyclerView(String id) { + mRecyclerView.setLayoutManager(new LinearLayoutManager(MyProfile.this)); + booksList = new ArrayList<>(); + adapter = new BookAdapter(this, id, booksList, this); + mRecyclerView.setAdapter(adapter); + adapter.setUpItemTouchHelper(mRecyclerView); + adapter.setUpAnimationDecoratorHelper(mRecyclerView); + } + + @Override + protected void onResume() { + super.onResume(); + + userName.setText(loader.getUserName(this)); + userEmail.setText(loader.getUserEmail(this)); + address.setText(loader.getRoomNo(this) + ", " + loader.getHostel(this)); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.change_password: + changePassword(); + return true; + case android.R.id.home: + onBackPressed(); + return true; + } + return (super.onOptionsItemSelected(item)); + } + + public void editProfileClicked(View view) { + Intent i = new Intent(this, EditProfileActivity.class); + startActivity(i); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + public void changeImageClicked(View view) { + final CharSequence[] items = {"Take Photo", "Choose from Library", + "Cancel"}; + AlertDialog.Builder builder = new AlertDialog.Builder(MyProfile.this); + builder.setTitle("Add Photo"); + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int item) { + if (items[item].equals("Take Photo")) { + userChoosenTask = "Take Photo"; + if (PermissionUtils.checkCameraPermission(MyProfile.this)) { + cameraIntent(); + } + } else if (items[item].equals("Choose from Library")) { + userChoosenTask = "Choose from Library"; + if (PermissionUtils.checkStoragePermission(MyProfile.this)) + galleryIntent(); + } else if (items[item].equals("Cancel")) { + dialog.dismiss(); + } + } + }); + builder.show(); + } + + private void cameraIntent() { + Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + startActivityForResult(intent, REQUEST_CAMERA); + } + + private void galleryIntent() { + Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + intent.setType("image/*"); + startActivityForResult(Intent.createChooser(intent, "Select File"), SELECT_FILE); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + switch (requestCode) { + case PermissionUtils.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + if (userChoosenTask.equals("Take Photo")) + cameraIntent(); + else if (userChoosenTask.equals("Choose from Library")) + galleryIntent(); + } else { + //code for deny + } + break; + } + } + + @Override + protected void onActivityResult(int reqCode, int resCode, Intent data) { + if (resCode == Activity.RESULT_OK && data != null) { + if (reqCode == SELECT_FILE) { + onGalleryImageResult(data); + } else if (reqCode == REQUEST_CAMERA) { + onCaptureImageResult(data); + } + } else if (reqCode == SEARCH_RESULTS_REQUEST_CODE){ + getUserInfoDetails(id); + } + } + + /* Checks if external storage is available for read and write */ + public boolean isExternalStorageWritable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state)) { + return true; + } + return false; + } + + private void onCaptureImageResult(Intent data) { + if (isExternalStorageWritable()) { + try { + Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes); + File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), + System.currentTimeMillis() + ".jpg"); + FileOutputStream fo; + fo = new FileOutputStream(file); + fo.write(bytes.toByteArray()); + fo.close(); + sendToServer(file); + } catch (FileNotFoundException e) { + e.printStackTrace(); + Toast.makeText(this, R.string.file_not_found, Toast.LENGTH_SHORT).show(); + + } catch (IOException e) { + Toast.makeText(this, "Unable to read the file", Toast.LENGTH_SHORT).show(); + e.printStackTrace(); + } catch (NullPointerException e) { + Toast.makeText(this, R.string.file_not_found, Toast.LENGTH_SHORT).show(); + e.printStackTrace(); + } catch (Exception e) { + Toast.makeText(this, "Unable to read the file", Toast.LENGTH_SHORT).show(); + e.printStackTrace(); + } + }else{ + Toast.makeText(this, "No extrenal storage available", Toast.LENGTH_SHORT).show(); + } + } + + private void onGalleryImageResult(Intent data) { + Uri uri = data.getData(); + Bitmap bitmap = null; + try { + bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (OutOfMemoryError e){ + Toast.makeText(this, "Image is too big to load!!", Toast.LENGTH_SHORT).show(); + } + File file = getFile(uri, bitmap); + if (file != null) { + sendToServer(file); + } else { + Toast.makeText(this, "Unable to upload image", Toast.LENGTH_SHORT).show(); + } + } + + public File getFile(Uri uri, Bitmap bitmap) { + + File file = null; + String path = FileUtils.getPath(this, uri); + if (path == null) { + try { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes); + file = new File(this.getCacheDir(), + System.currentTimeMillis() + ".jpg"); + FileOutputStream fo; + file.createNewFile(); + fo = new FileOutputStream(file); + fo.write(bytes.toByteArray()); + fo.close(); + } catch (IOException | NullPointerException e) { + e.printStackTrace(); + file = null; + } + } else { + try { + file = new File(path); + } catch (Exception e) { + e.printStackTrace(); + } + } + return file; + } + + public void sendToServer(File file) { + + UsersAPI api = NetworkingFactory.getLocalInstance().getUsersAPI(); + try { + File compressedFile = new Compressor.Builder(this) + .setMaxWidth(640) + .setMaxHeight(480) + .setQuality(75) + .setCompressFormat(Bitmap.CompressFormat.JPEG) + .build() + .compressToFile(file); + + RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpeg"), compressedFile); + MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody); + Call call = api.uploadImage("Token " + token, body, Helper.getUserId()); + Toast.makeText(getApplicationContext(), "Updating picture. Please wait.", Toast.LENGTH_SHORT).show(); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.body() != null) { + final String detail = response.body().getDetail(); + if (detail.equals("Profile picture changed")) { + Helper.imageChanged = true; + getProfilePicture(detail); + }else{ + Toast.makeText(MyProfile.this, detail, Toast.LENGTH_SHORT).show(); + } + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Toast.makeText(getApplicationContext(), "Please check your internet connection", Toast.LENGTH_SHORT).show(); + + } + }); + } catch (NullPointerException e) { + Toast.makeText(this, "Failed to load image", Toast.LENGTH_SHORT).show(); + } catch (OutOfMemoryError e){ + Toast.makeText(this, "Image is too big to upload!!", Toast.LENGTH_SHORT).show(); + } + } + + public void editBooksClicked(View view) { + Intent i = new Intent(this, MyProfile.class); + startActivity(i); + } + + public void changePassword() { + Intent i = new Intent(this, ChangePasswordActivity.class); + startActivity(i); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + finish(); + } + + @Override + protected void onStop() { + super.onStop(); + } + + @Override + protected void onPause() { + super.onPause(); + } + + @Override + protected void onRestart() { + super.onRestart(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/PasswordConfirmActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/PasswordConfirmActivity.java new file mode 100644 index 0000000..f86cc53 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/PasswordConfirmActivity.java @@ -0,0 +1,133 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.support.design.widget.TextInputEditText; +import android.support.design.widget.TextInputLayout; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AppCompatActivity; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; + +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class PasswordConfirmActivity extends AppCompatActivity { + + private TextView helperTextView; + private TextInputLayout newPasswordInputLayout, confirmPasswordInputLayout; + private TextInputEditText newPasswordEditText, confirmPasswordEditText; + private Button submitButton; + private Uri data; + private CustomProgressDialog progressDialog; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_password_confirm); + initViews(); + data = getIntent().getData(); + + newPasswordEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + String password = newPasswordEditText.getText().toString(); + if (TextUtils.isEmpty(password) || password.length() < 8){ + helperTextView.setTextColor(Color.RED); + } else{ + helperTextView.setTextColor(ContextCompat.getColor + (PasswordConfirmActivity.this, R.color.colorAccent)); + } + } + + @Override + public void afterTextChanged(Editable editable) { + } + }); + + submitButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (newPasswordEditText.getText().length() < 6){ + newPasswordInputLayout.setErrorEnabled(true); + confirmPasswordInputLayout.setErrorEnabled(false); + newPasswordInputLayout.setError("The password must be of atleast 8 characters"); + } else if(!newPasswordEditText.getText().toString().equals(confirmPasswordEditText.getText().toString())){ + newPasswordInputLayout.setErrorEnabled(false); + confirmPasswordInputLayout.setErrorEnabled(true); + confirmPasswordInputLayout.setError("The passwords do not match"); + } else { + newPasswordInputLayout.setEnabled(false); + confirmPasswordInputLayout.setEnabled(false); + progressDialog.show(); + resetPassword(); + } + } + }); + } + + private void resetPassword() { + String[] segments = data.getPath().split("/"); + UsersAPI usersApi = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call confirmPasswordCall = usersApi.confirmPassword( + segments[2], segments[3], + newPasswordEditText.getText().toString(), + confirmPasswordEditText.getText().toString()); + confirmPasswordCall.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + progressDialog.dismiss(); + if (response.isSuccessful()){ + Toast.makeText(PasswordConfirmActivity.this, "Password Updated Successfully", Toast.LENGTH_SHORT).show(); + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + finish(); + } + }, 500); + } else{ + newPasswordInputLayout.setEnabled(true); + confirmPasswordInputLayout.setEnabled(true); + Toast.makeText(PasswordConfirmActivity.this, "Please Try Again!", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + progressDialog.dismiss(); + newPasswordInputLayout.setEnabled(true); + confirmPasswordInputLayout.setEnabled(true); + t.printStackTrace(); + Toast.makeText(PasswordConfirmActivity.this, "Please Try Again!", Toast.LENGTH_SHORT).show(); + } + }); + } + + private void initViews() { + helperTextView = (TextView) findViewById(R.id.txt_reset_password_message); + newPasswordInputLayout = (TextInputLayout) findViewById(R.id.new_password_edit_text_layout); + confirmPasswordInputLayout = (TextInputLayout) findViewById(R.id.cnf_password_edit_text_layout); + newPasswordEditText = (TextInputEditText) findViewById(R.id.new_pwd_edit_text); + confirmPasswordEditText = (TextInputEditText) findViewById(R.id.cnf_pwd_edit_text); + submitButton = (Button) findViewById(R.id.reset_pwd_button); + progressDialog = new CustomProgressDialog(this); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SearchResultsActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SearchResultsActivity.java new file mode 100644 index 0000000..112de67 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SearchResultsActivity.java @@ -0,0 +1,310 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.support.v4.widget.NestedScrollView; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.text.InputType; +import android.view.KeyEvent; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.TextView; + +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentResult; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.ui.fragments.BookListFragment; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.RxSearchObservable; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.annotations.NonNull; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Predicate; +import io.reactivex.schedulers.Schedulers; + +public class SearchResultsActivity extends ActionBarActivity { + + private MenuItem mSearchAction; + private boolean isSearchOpened = false; + private EditText edtSeach; + private Toolbar mToolbar; + final List searchModeList = new ArrayList<>(); + + String query; + String API_KEY = CommonUtilities.API_KEY; + BookListFragment bookListFragment; + NestedScrollView scrollingView; + FloatingActionButton button; + Integer count = 0; + Spinner spinner;//This is used to know whether the search query is author or title, or can be anything + CustomProgressDialog customProgressDialog; + String selected = null; + String isbn; + ArrayAdapter dataAdapter; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.search_results); + + mToolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + mToolbar.setClickable(true); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + customProgressDialog = new CustomProgressDialog(SearchResultsActivity.this); + customProgressDialog.setCancelable(false); + scrollingView = (NestedScrollView) findViewById(R.id.scrollView); + button = (FloatingActionButton) findViewById(R.id.scroll); + + scrollingView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { + @Override + public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { + if (scrollY > 1000) { + button.setVisibility(View.VISIBLE); + } else { + button.setVisibility(View.INVISIBLE); + } + } + }); + + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + scrollingView.fullScroll(View.FOCUS_UP); + + } + }); + + bookListFragment = new BookListFragment(); + + search_open(); + + getFragmentManager() + .beginTransaction() + .replace(R.id.container, bookListFragment) + .commit(); + } + + public void barcodeScan(View view) { + new IntentIntegrator(SearchResultsActivity.this).initiateScan(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); + if (result != null) { + if (result.getContents() == null) { + //The operation was cancelled + } else { + isbn = result.getContents(); + bookListFragment.getBooks(isbn, "all", API_KEY); + } + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return (true); + } + + return (super.onOptionsItemSelected(item)); + } + + private void doSearch(String query, String mode) { + bookListFragment.getBooks(query, mode, API_KEY); + } + + public void hideKeyboard() { + View view = this.getCurrentFocus(); + if (view != null) { + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + } + + @Override + public void onBackPressed() { + if (isSearchOpened) { + handleMenuSearch(); + return; + } + super.onBackPressed(); + } + + protected void handleMenuSearch() { + ActionBar action = getSupportActionBar(); //get the actionbar + + + if (isSearchOpened) { //test if the search is open + + action.setDisplayShowCustomEnabled(false); //disable a custom view inside the actionbar + action.setDisplayShowTitleEnabled(true); //show the title in the action bar + + //hides the keyboard + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(edtSeach.getWindowToken(), 0); + + //add the search icon in the action bar + mSearchAction.setIcon(getResources().getDrawable(R.drawable.ic_search)); + + isSearchOpened = false; + } else { //open the search entry + + action.setDisplayShowCustomEnabled(true); //enable it to display a + // custom view in the action bar. + action.setCustomView(R.layout.book_search_bar);//add the custom view + action.setDisplayShowTitleEnabled(false); //hide the title + + edtSeach = (EditText) action.getCustomView().findViewById(R.id.searchEditText); //the text editor + edtSeach.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + + edtSeach.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + doSearch(edtSeach.getText().toString(), selected.toLowerCase()); + return true; + } + return false; + } + }); + edtSeach.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + edtSeach.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(edtSeach, InputMethodManager.SHOW_IMPLICIT); + } + }); + + edtSeach.requestFocus(); + + //open the keyboard focused in the edtSearch + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(edtSeach, InputMethodManager.SHOW_IMPLICIT); + + + //add the close icon + mSearchAction.setIcon(getResources().getDrawable(R.drawable.ic_clear_24dp)); + + isSearchOpened = true; + } + } + + private void search_open() { + ActionBar action = getSupportActionBar(); //get the actionbar + + action.setDisplayShowCustomEnabled(true); //enable it to display a + // custom view in the action bar. + action.setCustomView(R.layout.book_search_bar);//add the custom view + action.setDisplayShowTitleEnabled(false); //hide the title + + edtSeach = (EditText) action.getCustomView().findViewById(R.id.searchEditText); //the text editor + edtSeach.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + spinner = (Spinner) action.getCustomView().findViewById(R.id.spinner); + searchModeList.add("All"); + searchModeList.add("Author"); + searchModeList.add("Title"); + + // Creating adapter for spinner + dataAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, searchModeList); + + // Drop down layout style - list view with radio button + dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + + // attaching toReadName adapter to spinner + spinner.setAdapter(dataAdapter); + + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + selected = searchModeList.get(position); + } + + @Override + public void onNothingSelected(AdapterView parent) { + //Nothing is selected + } + }); + + spinner.setSelection(0);//Setting the user_default_image vaule of spinner to "All" + + edtSeach.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + edtSeach.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(edtSeach, InputMethodManager.SHOW_IMPLICIT); + } + }); + + edtSeach.requestFocus(); + //open the keyboard focused in the edtSearch + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(edtSeach, InputMethodManager.SHOW_IMPLICIT); + //add the close icon + + regRxObservable(); + } + + private void regRxObservable() { + InputMethodManager imm = (InputMethodManager) getApplication().getSystemService(Context.INPUT_METHOD_SERVICE); + RxSearchObservable.imm = imm; + RxSearchObservable.fromView(edtSeach) + .debounce(300, TimeUnit.MILLISECONDS) + .filter(new Predicate() { + @Override + public boolean test(String text) throws Exception { + if (text.isEmpty()) { + return false; + } else { + return true; + } + } + }) + .distinctUntilChanged() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onError(Throwable e) { + } + + @Override + public void onComplete() { + } + + @Override + public void onSubscribe(@NonNull Disposable disposable) { + } + + @Override + public void onNext(String s) { + doSearch(s, selected.toLowerCase()); + } + }); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SendEmailActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SendEmailActivity.java new file mode 100644 index 0000000..e990607 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SendEmailActivity.java @@ -0,0 +1,71 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.support.v7.app.AppCompatActivity; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.ui.fragments.SendEmailFragment; + +public class SendEmailActivity extends AppCompatActivity implements SendEmailFragment.OnFragmentInteractionListener{ + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_send_email); + + getIntentType((String) getIntent().getExtras().get("email_type")); + } + + private void getIntentType(String emailType) { + switch (emailType) { + case "forgot_password_email": + getSupportActionBar().setTitle("Forgot Password"); + initFragment(getResources().getString(R.string.forgot_password), + getResources().getString(R.string.forgot_password_message), + emailType); + break; + case "new_activation_email": + getSupportActionBar().setTitle("Activate Account"); + initFragment(getResources().getString(R.string.new_activation), + getResources().getString(R.string.new_activation_message), + emailType); + break; + case "new_otp": + getSupportActionBar().setTitle("Send Otp"); + initFragment(getResources().getString(R.string.new_otp), + getResources().getString(R.string.new_otp_message), + emailType); + break; + } + } + + private void initFragment(String title, String description, String emailType) { + FragmentManager fragmentManager = getFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + SendEmailFragment sendEmailFragment = SendEmailFragment.newInstance(title, description, emailType); + fragmentTransaction.add(R.id.send_email_fragment, sendEmailFragment); + fragmentTransaction.commit(); + } + + @Override + public void onFragmentInteraction(String status, String email) { + if (email != null){ + Intent verifyOtpIntent = new Intent(this, VerifyOtpActivity.class); + verifyOtpIntent.putExtra("email", email); + startActivity(verifyOtpIntent); + finish(); + }else { + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + finish(); + } + }, 1000); + } + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SignupActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SignupActivity.java new file mode 100644 index 0000000..e5c7d97 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SignupActivity.java @@ -0,0 +1,422 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.design.widget.TextInputLayout; +import android.support.v7.app.AppCompatActivity; +import android.text.InputType; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.firebase.iid.FirebaseInstanceId; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.Signup; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.Local.CollegeAdapter; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.ButterKnife; +import butterknife.InjectView; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class SignupActivity extends AppCompatActivity { + + private static final String TAG = AppCompatActivity.class.getSimpleName(); + + @InjectView(R.id.input_Fname) + EditText _FnameText; + @InjectView(R.id.input_Lname) + EditText _LnameText; + @InjectView(R.id.input_email) + EditText _emailText; + @InjectView(R.id.input_password) + EditText _passwordText; + @InjectView(R.id.input_cnf_password) + EditText _cnf_passwordText; + @InjectView(R.id.input_room_no) + EditText _roomText; + @InjectView(R.id.input_roll_no) + EditText _rollText; + @InjectView(R.id.hostel_spinner) + Spinner _hostelSpinner; + @InjectView(R.id.input_contact) + EditText _contactText; + @InjectView(R.id.btn_signup) + Button _signupButton; + @InjectView(R.id.link_login) + TextView _loginLink; + String hostel; + @InjectView(R.id._btn_show_password) + ImageButton _showPassword; + @InjectView(R.id._btn_show_cnf_password) + ImageButton _showCnfPassword; + @InjectView(R.id.domain_spinner) + Spinner _domainSpinner; + @InjectView(R.id.text_college_domain) + TextView domainTextView; + @InjectView(R.id.fname_input_layout) + TextInputLayout fnameInputLayout; + @InjectView(R.id.lname_input_layout) + TextInputLayout lnameInputLayout; + @InjectView(R.id.email_input_layout) + TextInputLayout emailInputLayout; + @InjectView(R.id.password_input_layout) + TextInputLayout passwordInputLayout; + @InjectView(R.id.confirm_password_input_layout) + TextInputLayout confirmPasswordInputLayout; + @InjectView(R.id.enroll_input_layout) + TextInputLayout enrollInputLayout; + ArrayAdapter hostelAdapter; + String domain = "@iitr.ac.in"; + ArrayList colleges; + int hostelResId = R.array.iitr_hostel_list; + boolean showPassword = false, showCnfPassword = false; + CustomProgressDialog progressDialog; + College college; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_signup); + ButterKnife.inject(this); + + colleges = new ArrayList<>(); + addColleges(); + CollegeAdapter collegeAdapter = new CollegeAdapter(getApplicationContext(), colleges); + _domainSpinner.setAdapter(collegeAdapter); + + _domainSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + college = (College) parent.getItemAtPosition(position); + domain = college.getCollegeDomain(); + domainTextView.setText(college.getCollegeDomain()); + getHostels(college.getCollegeName()); + setHostelSpinner(); + writeSharedPreferences(); + hostelAdapter.notifyDataSetChanged(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + domain = "@iitr.ac.in"; + hostelResId = R.array.iitr_hostel_list; + } + }); + + //Setting spinner for hostels + setHostelSpinner(); + writeSharedPreferences(); + + _signupButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + signup(hostel); + } + }); + + _loginLink.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // Finish the registration screen and return to the Login activity + finish(); + } + }); + + _showPassword.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!showPassword) { + _passwordText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); + _passwordText.setSelection(_passwordText.getText().length()); + showPassword = true; + _showPassword.setImageResource(R.drawable.ic_visible_on); + } else { + _passwordText.setInputType(129); //input type = password + showPassword = false; + _passwordText.setSelection(_passwordText.getText().toString().length()); + _showPassword.setImageResource(R.drawable.ic_visible_off); + } + } + + }); + _showCnfPassword.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!showCnfPassword) { + _cnf_passwordText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); + showCnfPassword = true; + _cnf_passwordText.setSelection(_cnf_passwordText.getText().toString().length()); + _showCnfPassword.setImageResource(R.drawable.ic_visible_on); + } else { + _cnf_passwordText.setInputType(129); //input type = password + showCnfPassword = false; + _cnf_passwordText.setSelection(_passwordText.getText().length()); + _showCnfPassword.setImageResource(R.drawable.ic_visible_off); + } + } + + }); + } + + private void writeSharedPreferences() { + SharedPreferences preferences = getSharedPreferences("hostel_res_id", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("hostel_id", hostelResId); + editor.apply(); + } + + private void getHostels(String collegeName) { + switch (collegeName) { + case "IIT Roorkee": + hostelResId = R.array.iitr_hostel_list; + break; + case "IIT Delhi": + hostelResId = R.array.iitd_hostel_list; + break; + case "IIT Bombay": + hostelResId = R.array.iitb_hostel_list; + break; + case "IIT Madras": + hostelResId = R.array.iitm_hostel_list; + break; + default: + hostelResId = R.array.iitr_hostel_list; + } + } + + private void setHostelSpinner() { + hostelAdapter = ArrayAdapter.createFromResource(this, hostelResId, android.R.layout.simple_spinner_item); + hostelAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + _hostelSpinner.setAdapter(hostelAdapter); + _hostelSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + hostel = parent.getItemAtPosition(position).toString(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + hostel = (String) parent.getItemAtPosition(0); + } + }); + } + + public void signup(String hostel) { + + if (!validate()) { + onSignupFailed("Fill required details properly."); + return; + } + + progressDialog = new CustomProgressDialog(SignupActivity.this); + progressDialog.setCancelable(false); + + String fname = _FnameText.getText().toString(); + String lname = _LnameText.getText().toString(); + String email = _emailText.getText().toString() + domain; + String password = _passwordText.getText().toString(); + String room_no = _roomText.getText().toString(); + String roll_no = _rollText.getText().toString(); + String contact = _contactText.getText().toString(); + + requestSignUp(fname, lname, email, password, room_no, roll_no, college.getCollegeName(), contact); + } + + private void requestSignUp(final String fname, final String lname, final String email, final String password, + final String room_no, final String roll_no, final String college, final String contact) { + progressDialog.show(); + Helper.setUserEmail(email); + final UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + + Call> collegeListCall = usersAPI.searchCollege(college); + collegeListCall.enqueue(new Callback>() { + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + if (response.body() == null || response.body().size() == 0) { + Call addCollegeCall = usersAPI.addCollege(college, domain); + addCollegeCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.body() != null) { + Log.i(TAG, "College Made" + response.toString()); + createAccount(usersAPI, fname, lname, email, college, room_no, roll_no, contact, + password); + } else { + Log.i(TAG, "College Not Made" + response.toString()); + progressDialog.dismiss(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.i(TAG, "College Not Made" + t.toString()); + progressDialog.dismiss(); + } + }); + } else { + createAccount(usersAPI, fname, lname, email, college, room_no, roll_no, contact, password); + } + } + + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + Log.i(TAG, "College Not Made" + t.toString()); + progressDialog.dismiss(); + } + }); + } + + public void createAccount(UsersAPI usersAPI, String fname, String lname, String email, String college, + String room_no, String roll_no, String contact, String password) { + + Call userInfoCall = usersAPI.getUserInfo(email, hostel, room_no, roll_no, fname, lname, contact, + FirebaseInstanceId.getInstance().getToken(), password, college); + userInfoCall.enqueue(new retrofit2.Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + onSignupFailed("Check your network connection properly"); + progressDialog.dismiss(); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.body() != null) { + String detail = response.body().getDetail(); + + if (detail.equals("Successfully registered.")) { + onSignupSuccess(); + } else { + onSignupFailed(detail); + progressDialog.dismiss(); + } + } + } + }); + } + + public void onSignupSuccess() { + _signupButton.setEnabled(true); + progressDialog.dismiss(); + if (_contactText.getText().toString().equals("")) { + showAlertDialog(); + } else{ + Intent verifyOtpIntent = new Intent(SignupActivity.this, VerifyOtpActivity.class); + verifyOtpIntent.putExtra("email", _emailText.getText().toString() + domain); + startActivity(verifyOtpIntent); + finish(); + } + } + + private void showAlertDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Success!!"); + builder.setMessage("An activation link has been sent to your email. Click it to activate your citadel account."); + builder.setNeutralButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + finish(); + } + }); + AlertDialog dialog = builder.create(); + dialog.setCancelable(false); + dialog.show(); + } + + public void onSignupFailed(String toast) { + Toast.makeText(getBaseContext(), toast, Toast.LENGTH_LONG).show(); + _signupButton.setEnabled(true); + } + + public boolean validate() { + boolean valid = true; + + String fname = _FnameText.getText().toString(); + String lname = _LnameText.getText().toString(); + String email = _emailText.getText().toString() + domain; + String password = _passwordText.getText().toString(); + String cnf_password = _cnf_passwordText.getText().toString(); + String roll_no = _rollText.getText().toString(); + + if (fname.isEmpty()) { + fnameInputLayout.setErrorEnabled(true); + fnameInputLayout.setError("Please fill first name"); + valid = false; + } else { + fnameInputLayout.setErrorEnabled(false); + } + if (lname.isEmpty()) { + lnameInputLayout.setErrorEnabled(true); + lnameInputLayout.setError("Please fill last lame"); + valid = false; + } else { + lnameInputLayout.setErrorEnabled(false); + } + if (email.isEmpty()) { + emailInputLayout.setErrorEnabled(true); + emailInputLayout.setError("Enter a valid email address"); + valid = false; + } else { + emailInputLayout.setErrorEnabled(false); + } + if (password.isEmpty() || password.length() < 6 || password.length() > 15) { + passwordInputLayout.setErrorEnabled(true); + passwordInputLayout.setError("Password must be at least 6 characters in length"); + valid = false; + } else { + passwordInputLayout.setErrorEnabled(false); + } + if (cnf_password.isEmpty() || !(cnf_password.equals(password))) { + if (cnf_password.isEmpty()) { + confirmPasswordInputLayout.setErrorEnabled(true); + confirmPasswordInputLayout.setError("Please re-enter password"); + } else { + confirmPasswordInputLayout.setErrorEnabled(true); + confirmPasswordInputLayout.setError("The passwords do not match."); + } + valid = false; + } else { + confirmPasswordInputLayout.setErrorEnabled(false); + } + if (roll_no.isEmpty()) { + enrollInputLayout.setErrorEnabled(true); + enrollInputLayout.setError("Please fill enollment no"); + valid = false; + + } else { + enrollInputLayout.setErrorEnabled(false); + } + return valid; + } + + private void addColleges() { + colleges.add(new College(getResources().getString(R.string.iitr), "@iitr.ac.in")); + colleges.add(new College(getResources().getString(R.string.iitd), "@iitd.ac.in")); + colleges.add(new College(getResources().getString(R.string.iitb), "@iitb.ac.in")); + colleges.add(new College(getResources().getString(R.string.iitm), "@iitm.ac.in")); +// colleges.add(new College("IIT Kanpur", "@iitk.ac.in")); +// colleges.add(new College("IIT Kharagpur", "@iitkgp.ac.in")); +// colleges.add(new College("IIT Guwahati", "@iitg.ac.in")); +// colleges.add(new College("IIT Ropar", "@iitrp.ac.in")); +// colleges.add(new College("IIT Indore", "@iiti.ac.in")); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SplashScreen.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SplashScreen.java new file mode 100644 index 0000000..35856a5 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/SplashScreen.java @@ -0,0 +1,212 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; + +import java.util.Iterator; +import java.util.Set; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class SplashScreen extends Activity { + + String token; + String extra_data = "none"; + SharedPreferences pref, firstLaunchSharedPreferences; + SharedPreferences.Editor editor; + private static final String FIRST_LAUNCH_PREF_NAME = "is_first_launch"; + private static final String IS_FIRST_TIME_LAUNCH = "is_first_time_launch"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + // TODO Auto-generated method stub + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_splash_screen); + + firstLaunchSharedPreferences = getSharedPreferences(FIRST_LAUNCH_PREF_NAME, MODE_PRIVATE); + + pref = getApplicationContext().getSharedPreferences("Token", MODE_PRIVATE); + token = pref.getString("token", null); + + if (getIntent().getExtras() != null) { + String data = getIntent().getExtras().getString("google.message_id"); + if (data != null) { + extra_data = "open_drawer"; + } + dumpIntent(getIntent()); + } + + if (isOnline()) { + verifyToken(); + } else if (token != null) { + if (isFirstTimeLaunch()){ + launchFirstTime("data_splash", extra_data); + } else { + Intent intent = new Intent(SplashScreen.this, MainActivity.class); + intent.putExtra("data_splash", extra_data); + startActivity(intent); + finish(); + } + } else{ + if (isFirstTimeLaunch()){ + launchFirstTime("toast_message", "There is no internet connection!"); + } else { + Toast.makeText(SplashScreen.this, "There is no internet connection!", Toast.LENGTH_LONG).show(); + Intent intent = new Intent(SplashScreen.this, LoginActivity.class); + startActivity(intent); + finish(); + } + } + } + + /** + * Method to launch the welcome activity + * @param intentTag the tag associated with the intent + * @param intentData the toReadName associated with the intent + */ + private void launchFirstTime(String intentTag, String intentData) { + editor = firstLaunchSharedPreferences.edit(); + editor.putBoolean(IS_FIRST_TIME_LAUNCH, false); + editor.apply(); + Intent intent = new Intent(SplashScreen.this, WelcomeActivity.class); + intent.putExtra(intentTag, intentData); + startActivity(intent); + finish(); + } + + public boolean isOnline() { + ConnectivityManager cm = + (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo netInfo = cm.getActiveNetworkInfo(); + return netInfo != null && netInfo.isConnectedOrConnecting(); + } + + public void verifyToken() { + + if (token != null) { + + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = usersAPI.getUserEmail("Token " + token); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.body() != null) { + if (response.body().getDetail() != null) { + if (!response.body().getDetail().equals("")) { + Helper.setUserEmail(response.body().getDetail()); + if (isFirstTimeLaunch()){ + launchFirstTime("data_splash", extra_data); + } else{ + Intent intent = new Intent(SplashScreen.this, MainActivity.class); + intent.putExtra("data_splash", extra_data); + startActivity(intent); + finish(); + } + } else { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (isFirstTimeLaunch()){ + launchFirstTime("toast_message", "Failed to Log in"); + }else { + Toast.makeText(SplashScreen.this, "Failed to Log in", Toast.LENGTH_LONG).show(); + Intent intent = new Intent(SplashScreen.this, LoginActivity.class); + startActivity(intent); + finish(); + } + } + } + } else { + if (isFirstTimeLaunch()){ + launchFirstTime("toast_message", "Failed to Log in"); + }else { + Toast.makeText(SplashScreen.this, "Failed to Log in", Toast.LENGTH_LONG).show(); + Intent intent = new Intent(SplashScreen.this, LoginActivity.class); + startActivity(intent); + finish(); + } + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (isFirstTimeLaunch()){ + launchFirstTime("toast_message", "Failed to Log in"); + }else { + Toast.makeText(SplashScreen.this, "Failed to Login", Toast.LENGTH_SHORT).show(); + Intent i = new Intent(getApplicationContext(), LoginActivity.class); + startActivity(i); + finish(); + } + } + }); + } else { + if (isFirstTimeLaunch()){ + editor = firstLaunchSharedPreferences.edit(); + editor.putBoolean(IS_FIRST_TIME_LAUNCH, false); + editor.apply(); + Handler h = new Handler(); + Runnable r = new Runnable() { + @Override + public void run() { + Intent i = new Intent(getApplicationContext(), WelcomeActivity.class); + startActivity(i); + finish(); + } + }; + h.postDelayed(r, 1500); + }else { + Handler h = new Handler(); + Runnable r = new Runnable() { + @Override + public void run() { + Intent i = new Intent(getApplicationContext(), LoginActivity.class); + startActivity(i); + finish(); + } + }; + h.postDelayed(r, 1500); + } + } + } + + public static void dumpIntent(Intent i) { + + Bundle bundle = i.getExtras(); + if (bundle != null) { + Set keys = bundle.keySet(); + Iterator it = keys.iterator(); + } + } + + /** + * to check whether the app is opened for the first time + * @return boolean telling whether the app is opened first + */ + public boolean isFirstTimeLaunch() { + return firstLaunchSharedPreferences.getBoolean(IS_FIRST_TIME_LAUNCH, true); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/ToReadActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/ToReadActivity.java new file mode 100644 index 0000000..fc18141 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/ToReadActivity.java @@ -0,0 +1,160 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.Listeners.EndlessScrollListener; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.BooksAPI; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.models.BookDetailsToRead; +import com.sdsmdg.bookshareapp.BSA.api.models.GoodreadsResponse3; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.GR.BooksAdapterToRead; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + + +public class ToReadActivity extends AppCompatActivity { + + RecyclerView localBookList; + List bookDetailsToReads = new ArrayList<>(); + BooksAdapterToRead adapter; + LinearLayoutManager layoutManager; + SwipeRefreshLayout refreshLayout; + SharedPreferences pref; + String userGrId; + CustomProgressDialog customProgressDialog; + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_to_read, menu); + return true; + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_toread); + customProgressDialog = new CustomProgressDialog(ToReadActivity.this); + customProgressDialog.setCancelable(false); + customProgressDialog.show(); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + pref = getSharedPreferences("UserId", MODE_PRIVATE); + userGrId = pref.getString("userGrId", null); + + adapter = new BooksAdapterToRead(this, bookDetailsToReads, new BooksAdapterToRead.OnItemClickListener() { + @Override + public void onItemClick(BookDetailsToRead booktoRead) { + } + }); + + layoutManager = new LinearLayoutManager(this); + + localBookList = (RecyclerView) findViewById(R.id.local_books_list); + localBookList.setLayoutManager(layoutManager); + localBookList.setAdapter(adapter); + + final EndlessScrollListener endlessScrollListener = new EndlessScrollListener((LinearLayoutManager) layoutManager) { + @Override + public void onLoadMore(int page, int totalItemsCount) { + getToReadBooks(); + Toast.makeText(getApplicationContext(), "Loading Page " + (page + 1), Toast.LENGTH_SHORT).show(); + } + }; + + localBookList.addOnScrollListener(endlessScrollListener); + refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_to_refresh_layout); + refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + endlessScrollListener.reset(); + getToReadBooks(); + } + + }); + + getToReadBooks(); + } + + public void getToReadBooks() { + BooksAPI api = NetworkingFactory.getGRInstance().getBooksApi(); + HashMap params = new HashMap<>(); + params.put("key", CommonUtilities.API_KEY); + params.put("id", userGrId); + params.put("shelf", "to-read"); + Call call = api.getToRead(params); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.body() != null) { + bookDetailsToReads.clear(); + adapter.notifyDataSetChanged(); + bookDetailsToReads.addAll(response.body().getBookDetailsToReads()); + adapter.notifyDataSetChanged(); + refreshLayout.setRefreshing(false); + } + + final android.os.Handler handler = new android.os.Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + customProgressDialog.dismiss(); + } + }, 1000); + + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + refreshLayout.setRefreshing(false); + customProgressDialog.dismiss(); + + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + + case R.id.action_settings: + SharedPreferences.Editor editor = pref.edit(); + editor.putString("userGrId", null); + editor.apply(); + Helper.setUserGRid(null); + + Intent i = new Intent(this, MainActivity.class); + startActivity(i); + finish(); + return true; + + default: + return super.onOptionsItemSelected(item); + } + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/UserProfile.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/UserProfile.java new file mode 100644 index 0000000..9749c33 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/UserProfile.java @@ -0,0 +1,297 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.v4.widget.NestedScrollView; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.jakewharton.picasso.OkHttp3Downloader; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserDetailWithCancel; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.Local.BooksAdapterRequest; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.squareup.picasso.MemoryPolicy; +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import jp.wasabeef.blurry.Blurry; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +import static android.view.View.GONE; + + +public class UserProfile extends AppCompatActivity { + TextView name, emailTextView, address, booksCount; + UserInfo user; + List booksList; + BooksAdapterRequest adapter; + ImageView callIcon; + ImageView profile_picture, background_image; + String contactNo; + String email; + NestedScrollView scrollView; + CustomProgressDialog customProgressDialog; + SharedPreferences prefs; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_user_profile); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + customProgressDialog = new CustomProgressDialog(UserProfile.this); + customProgressDialog.setCancelable(false); + customProgressDialog.show(); + prefs = getApplicationContext().getSharedPreferences("Token", Context.MODE_PRIVATE); + + name = (TextView) findViewById(R.id.user_name); + emailTextView = (TextView) findViewById(R.id.user_email); + address = (TextView) findViewById(R.id.address); + callIcon = (ImageView) findViewById(R.id.call_icon); + profile_picture = (ImageView) findViewById(R.id.profile_picture); + background_image = (ImageView) findViewById(R.id.background_image); + booksCount = (TextView) findViewById(R.id.books_count); + scrollView = (NestedScrollView) findViewById(R.id.scroll); + + String id = getIntent().getExtras().getString("id"); + + RecyclerView userBooksList = (RecyclerView) findViewById(R.id.user_books_list_view); + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); + userBooksList.setLayoutManager(layoutManager); + booksList = new ArrayList<>(); + adapter = new BooksAdapterRequest(this, booksList, new BooksAdapterRequest.OnItemClickListener() { + @Override + public void onItemClick(Book book) { + Log.i("Click", "onItemClick"); + } + }, id); + + userBooksList.setAdapter(adapter); + userBooksList.setNestedScrollingEnabled(false); + + getUserInfoDetails(id); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return (true); + } + + return (super.onOptionsItemSelected(item)); + } + + public void getUserInfoDetails(final String id) { + Log.i("INSIDE ONCLICK ", id + "fklksmlsn"); + + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + + OkHttpClient.Builder httpclient = new OkHttpClient.Builder().addInterceptor(interceptor); + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(CommonUtilities.local_books_api_url) + .addConverterFactory(GsonConverterFactory.create()) + .client(httpclient.build()) + .build(); + + UsersAPI api = retrofit.create(UsersAPI.class); + Call call = api.getUserDetails(id, id, "Token " + prefs + .getString("token", null)); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, + @NonNull Response response) { + if (response.body() != null) { + user = response.body().getUserInfo(); + name.setText(user.getName()); + email = user.getEmail(); + emailTextView.setText(email); + contactNo = user.getContactNo(); + hideDisplayCallIcon(contactNo); + address.setText(getAddress(user.getRoomNo(), user.getHostel())); + getProfilePicture(user.getId()); + + List booksTempInfoList = user.getUserBookList(); + String bookCount = "Books(" + booksTempInfoList.size() + ")"; + booksCount.setText(bookCount); + booksList.clear(); + booksList.addAll(booksTempInfoList); + adapter.setCancels(response.body().getCancels()); + adapter.notifyDataSetChanged(); + } + + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + customProgressDialog.dismiss(); + } + }, 1000); + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.d("BookDetails fail", t.toString()); + customProgressDialog.dismiss(); + + } + }); + } + + private void getProfilePicture(final String id) { + Picasso.Builder builder = new Picasso.Builder(UserProfile.this); + builder.listener(new Picasso.Listener() { + @Override + public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) { + exception.printStackTrace(); + } + }); + builder.downloader(new OkHttp3Downloader(getOkHttpClient())) + .build() + .load(CommonUtilities.getAnotherUserImageUrl(id)) + .memoryPolicy(MemoryPolicy.NO_CACHE) + .into(new Target() { + @Override + public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { + profile_picture.setImageBitmap(bitmap); + background_image.setImageBitmap(bitmap); + Blurry.with(getApplicationContext()) + .radius(40) + .sampling(1) + .color(Color.argb(66, 0, 0, 0)) + .async() + .capture(findViewById(R.id.background_image)) + .into((ImageView) findViewById(R.id.background_image)); + } + + @Override + public void onBitmapFailed(Drawable errorDrawable) { + profile_picture.setImageResource(R.drawable.user_default_image); + background_image.setImageResource(R.drawable.user_default_image); + Blurry.with(getApplicationContext()) + .radius(40) + .sampling(1) + .color(Color.argb(66, 0, 0, 0)) + .async() + .capture(findViewById(R.id.background_image)) + .into((ImageView) findViewById(R.id.background_image)); + } + + @Override + public void onPrepareLoad(Drawable placeHolderDrawable) { + } + }); + } + + private OkHttpClient getOkHttpClient() { + OkHttpClient client = new OkHttpClient.Builder() + .addInterceptor(new Interceptor() { + @Override + public okhttp3.Response intercept(@NonNull Chain chain) throws IOException { + Request newRequest = chain.request().newBuilder() + .addHeader("Authorization", "Token " + prefs + .getString("token", null)) + .build(); + return chain.proceed(newRequest); + } + }).build(); + return client; + } + + private String getAddress(String roomNo, String hostel) { + String ad; + if (roomNo == null) { + ad = hostel; + } else { + ad = roomNo + ", " + hostel; + } + return ad; + } + + private void hideDisplayCallIcon(String contactNo) { + if (contactNo == null || Objects.equals(contactNo, "")) { + callIcon.setVisibility(GONE); + } + } + + public void callClicked(View view) { + final CharSequence[] items = {"Call", "Copy Contact Number", "Cancel"}; + AlertDialog.Builder builder = new AlertDialog.Builder(UserProfile.this); + builder.setTitle("Do you want to :"); + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (items[which].equals("Call")) { + + String uri = "tel:" + contactNo.trim(); + + Intent i = new Intent(Intent.ACTION_DIAL); + i.setData(Uri.parse(uri)); + startActivity(i); + } else if (items[which].equals("Copy Contact Number")) { + ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("Contact No.", contactNo.trim()); + clipboard.setPrimaryClip(clip); + Toast.makeText(UserProfile.this, "Contact Number Copied", Toast.LENGTH_SHORT).show(); + } else { + dialog.dismiss(); + + } + } + }); + builder.show(); + + } + + public void emailClicked(View view) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/html"); + intent.putExtra(Intent.EXTRA_EMAIL, email); + startActivity(Intent.createChooser(intent, "Send Email")); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + finish(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/UserSearchActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/UserSearchActivity.java new file mode 100644 index 0000000..4237111 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/UserSearchActivity.java @@ -0,0 +1,261 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.text.InputType; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.Local.UsersAdapter; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; +import com.sdsmdg.bookshareapp.BSA.utils.RxSearchObservable; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import io.reactivex.schedulers.Schedulers; + +public class UserSearchActivity extends ActionBarActivity { + + private MenuItem mSearchAction; + private boolean isSearchOpened = false; + private EditText edtSeach; + + RecyclerView usersRecyclerView; + List userInfoList = new ArrayList<>(); + SharedPreferences preferences; + UsersAdapter adapter; + TextView noUsersTextView; + CustomProgressDialog customProgressDialog; + private Toolbar mToolbar; + private ProgressBar progressBar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_user_search); + + mToolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + + mToolbar.setClickable(true); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + customProgressDialog = new CustomProgressDialog(UserSearchActivity.this); + customProgressDialog.setCancelable(false); + + noUsersTextView = (TextView) findViewById(R.id.no_users_textView); + progressBar = (ProgressBar) findViewById(R.id.indeterminateBar); + preferences = getSharedPreferences("Token", MODE_PRIVATE); + + search_open(); + usersRecyclerView = (RecyclerView) findViewById(R.id.user_list); + usersRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + + adapter = new UsersAdapter(false, Helper.getUserId(), this, userInfoList, null, null, new UsersAdapter.OnItemClickListener() { + @Override + public void onItemClick(UserInfo userInfo) { + } + }); + usersRecyclerView.setAdapter(adapter); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + mSearchAction = menu.findItem(R.id.action_search); + return super.onPrepareOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + case R.id.action_settings: + return true; + case R.id.action_search: + return true; + } + return (super.onOptionsItemSelected(item)); + } + + private Observable> dataFromNetwork(final String query) { + UsersAPI api = NetworkingFactory.getLocalInstance().getUsersAPI(); + SharedPreferences preferences = getSharedPreferences("Token", MODE_PRIVATE); + return api.searchUser + (query, "Token " + preferences.getString("token", null)) + .subscribeOn(Schedulers.io()); + } + + @Override + public void onBackPressed() { + if (isSearchOpened) { + handleMenuSearch(); + return; + } + super.onBackPressed(); + } + + protected void handleMenuSearch() { + ActionBar action = getSupportActionBar(); //get the actionbar + + if (isSearchOpened) { + //test if the search is open + action.setDisplayShowCustomEnabled(false); //disable a custom view inside the actionbar + action.setDisplayShowTitleEnabled(true); //show the title in the action bar + + //hides the keyboard + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(edtSeach.getWindowToken(), 0); + + //add the search icon in the action bar + //mSearchAction.setIcon(getResources().getDrawable(R.drawable.ic_search)); + isSearchOpened = false; + } else { + //open the search entry + action.setDisplayShowCustomEnabled(true); //enable it to display a + // custom view in the action bar. + action.setCustomView(R.layout.user_search_bar); //add the custom view + action.setDisplayShowTitleEnabled(false); //hide the title + + edtSeach = (EditText) action.getCustomView().findViewById(R.id.edtSearch); //the text editor + edtSeach.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + //this is a listener to do a search when the user clicks on search button + edtSeach.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + edtSeach.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(edtSeach, InputMethodManager.SHOW_IMPLICIT); + } + }); + + edtSeach.requestFocus(); + + //open the keyboard focused in the edtSearch + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(edtSeach, InputMethodManager.SHOW_IMPLICIT); + + //add the close icon + mSearchAction.setIcon(getResources().getDrawable(R.drawable.ic_cross)); + isSearchOpened = true; + } + } + + private void search_open() { + ActionBar action = getSupportActionBar(); //get the actionbar + + action.setDisplayShowCustomEnabled(true); //enable it to display a + // custom view in the action bar. + action.setCustomView(R.layout.user_search_bar); //add the custom view + action.setDisplayShowTitleEnabled(false); //hide the title + edtSeach = (EditText) action.getCustomView().findViewById(R.id.edtSearch); //the text editor + edtSeach.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + + edtSeach.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + edtSeach.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(edtSeach, InputMethodManager.SHOW_IMPLICIT); + + } + }); + + edtSeach.requestFocus(); + + //open the keyboard focused in the edtSearch + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(edtSeach, InputMethodManager.SHOW_IMPLICIT); + + regRxObservable(); + } + + private void regRxObservable() { + InputMethodManager imm = (InputMethodManager) getApplication().getSystemService(Context.INPUT_METHOD_SERVICE); + RxSearchObservable.imm = imm; + RxSearchObservable.fromView(edtSeach) + .debounce(300, TimeUnit.MILLISECONDS) + .distinctUntilChanged() + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(new Consumer() { + @Override + public void accept(String s) throws Exception { + showProgressBar(); + } + }) + .switchMap(new Function>>() { + @Override + public ObservableSource> apply(String query) throws Exception { + return dataFromNetwork(query); + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer>() { + @Override + public void accept(List userInfos) throws Exception { + hideProgressBar(); + showResults(userInfos); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + hideProgressBar(); + Toast.makeText(getApplicationContext(), R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + + private void showResults(List userInfos) { + userInfoList.clear(); + userInfoList.addAll(userInfos); + if (userInfoList.size() == 0){ + noUsersTextView.setVisibility(View.VISIBLE); + usersRecyclerView.setVisibility(View.GONE); + }else{ + noUsersTextView.setVisibility(View.GONE); + usersRecyclerView.setVisibility(View.VISIBLE); + } + adapter.notifyDataSetChanged(); + } + + private void hideProgressBar() { + progressBar.setVisibility(View.GONE); + } + + private void showProgressBar() { + progressBar.setVisibility(View.VISIBLE); + noUsersTextView.setVisibility(View.GONE); + usersRecyclerView.setVisibility(View.GONE); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/VerifyOtpActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/VerifyOtpActivity.java new file mode 100644 index 0000000..8d87d1c --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/VerifyOtpActivity.java @@ -0,0 +1,435 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.app.AlertDialog; +import android.app.Service; +import android.content.ComponentName; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.design.widget.TextInputEditText; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v4.view.ViewCompat; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.AppCompatEditText; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.Listeners.SmsListener; +import com.sdsmdg.bookshareapp.BSA.Listeners.SmsReceiver; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class VerifyOtpActivity extends AppCompatActivity implements + View.OnFocusChangeListener, TextWatcher, SmsListener { + + private static final int MY_PERMISSIONS_REQUEST_READ_SMS = 100; + private TextInputEditText pinFirstDigitEditText; + private TextInputEditText pinSecondDigitEditText; + private TextInputEditText pinThirdDigitEditText; + private TextInputEditText pinFourthDigitEditText; + private TextInputEditText pinFifthDigitEditText; + private TextInputEditText pinSixthDigitEditText; + private TextInputEditText pinHiddenEditText; + private Button submitOtpButton; + private CustomProgressDialog progressDialog; + private String email = null; + private String contact = null; + private SharedPreferences preferences; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_verify_otp); + initViews(); + setPinListeners(); + checkSmsPermission(); + bindListeners(); + regListeners(); + if (getIntent().getExtras() != null){ + email = (String) getIntent().getExtras().get("email"); + contact = (String) getIntent().getExtras().get("contact"); + } + } + + /** + * Register listeners for button click + */ + private void regListeners() { + submitOtpButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (pinHiddenEditText.getText().length() == 6){ + submitOtpButton.setEnabled(false); + progressDialog = new CustomProgressDialog(VerifyOtpActivity.this); + progressDialog.setCancelable(false); + progressDialog.show(); + final UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call verifyOtpCall; + if (contact == null) { + verifyOtpCall = usersAPI. + verifyOtp(email, pinHiddenEditText.getText().toString()); + }else{ + verifyOtpCall = usersAPI. + changeMobile("Token " + preferences.getString("token", null), + email, contact, pinHiddenEditText.getText().toString()); + } + verifyOtpCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.body() != null){ + String detail = response.body().getDetail(); + if (detail.equals("Congratulations, the mobile has been verified!!")) { + onSignupSuccess(); + } else { + onSignupFailed("The otp entered is incorrect."); + progressDialog.dismiss(); + } + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + onSignupFailed("Check your network connection properly"); + progressDialog.dismiss(); + } + }); + } else{ + Toast.makeText(VerifyOtpActivity.this, + "The otp must be at least 6 numbers in length", Toast.LENGTH_SHORT).show(); + } + } + }); + } + + public void onSignupSuccess() { + submitOtpButton.setEnabled(true); + progressDialog.dismiss(); + showSuccessUI(); + } + + private void showSuccessUI() { + if (contact == null) { + showAlertDialog(); + }else { + Toast.makeText(this, "Congratulations!! the mobile is verified", Toast.LENGTH_SHORT).show(); + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + SharedPreferences.Editor editor = preferences.edit(); + editor.putString("contact_no", contact); + editor.apply(); + finish(); + + } + }, 1000); + } + } + + private void showAlertDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Success!!"); + builder.setMessage("An activation link has been sent to your email. Click it to activate your citadel account."); + builder.setNeutralButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + finish(); + } + }); + AlertDialog dialog = builder.create(); + dialog.setCancelable(false); + dialog.show(); + } + + public void onSignupFailed(String toast) { + Toast.makeText(getBaseContext(), toast, Toast.LENGTH_LONG).show(); + submitOtpButton.setEnabled(true); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + Toast.makeText(this, "The mobile number is not verified", Toast.LENGTH_SHORT).show(); + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + if (contact == null) { + Intent loginIntent = new Intent(VerifyOtpActivity.this, LoginActivity.class); + loginIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + startActivity(loginIntent); + finish(); + }else{ + finish(); + } + } + }, 1000); + } + + /** + * Check permission for reading sms + */ + private void checkSmsPermission() { + // Here, thisActivity is the current activity + if (ContextCompat.checkSelfPermission(this, + android.Manifest.permission.READ_SMS) + != PackageManager.PERMISSION_GRANTED) { + + // Should we show an explanation? + if (ActivityCompat.shouldShowRequestPermissionRationale(this, + android.Manifest.permission.READ_SMS)) { + // Show an explanation to the user *asynchronously* -- don't block + // this thread waiting for the user's response! After the user + // sees the explanation, try again to request the permission. + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Read Sms Permission"); + builder.setMessage("Allow Citadel app to read your sms to automatically verify one time password sent."); + AlertDialog dialog = builder.create(); + dialog.show(); + } else { + // No explanation needed, we can request the permission. + ActivityCompat.requestPermissions(this, + new String[]{android.Manifest.permission.READ_SMS}, + MY_PERMISSIONS_REQUEST_READ_SMS); + // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an + // app-defined int constant. The callback method gets the + // result of the request. + } + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + switch (requestCode){ + case MY_PERMISSIONS_REQUEST_READ_SMS: + // If request is cancelled, the result arrays are empty. + if (grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // permission was granted, yay! Do the + // contacts-related task you need to do. + PackageManager pm = this.getPackageManager(); + ComponentName componentName = new ComponentName(this, SmsReceiver.class); + pm.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + } else { + // permission denied, boo! Disable the + // functionality that depends on this permission. + PackageManager pm = this.getPackageManager(); + ComponentName componentName = new ComponentName(this, SmsReceiver.class); + pm.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + break; + } + } + + /** + * Bind to receiver to receive message + */ + private void bindListeners() { + SmsReceiver.bindListener(this); + } + + /** + * Initialize EditText fields. + */ + private void initViews() { + pinFirstDigitEditText = (TextInputEditText) findViewById(R.id.txt_first_pin); + pinSecondDigitEditText = (TextInputEditText) findViewById(R.id.txt_second_pin); + pinThirdDigitEditText = (TextInputEditText) findViewById(R.id.txt_third_pin); + pinFourthDigitEditText = (TextInputEditText) findViewById(R.id.txt_fourth_pin); + pinFifthDigitEditText = (TextInputEditText) findViewById(R.id.txt_fifth_pin); + pinSixthDigitEditText = (TextInputEditText) findViewById(R.id.txt_sixth_pin); + pinHiddenEditText = (TextInputEditText) findViewById(R.id.pin_hidden_edittext); + submitOtpButton = (Button) findViewById(R.id.submit_otp_button); + preferences = getSharedPreferences("Token", MODE_PRIVATE); + } + + /** + * Sets listeners for EditText fields. + */ + private void setPinListeners() { + pinHiddenEditText.addTextChangedListener(this); + + pinFirstDigitEditText.setOnFocusChangeListener(this); + pinSecondDigitEditText.setOnFocusChangeListener(this); + pinThirdDigitEditText.setOnFocusChangeListener(this); + pinFourthDigitEditText.setOnFocusChangeListener(this); + pinFifthDigitEditText.setOnFocusChangeListener(this); + pinSixthDigitEditText.setOnFocusChangeListener(this); + } + + @Override + public void onFocusChange(View view, boolean b) { + if (b) { + if (pinHiddenEditText.getText().length() == 0){ + setFocusedPinBackground(pinFirstDigitEditText); + } + if (pinHiddenEditText.getText().length() == 6){ + setFocusedPinBackground(pinSixthDigitEditText); + } + setFocus(pinHiddenEditText); + showSoftKeyboard(pinHiddenEditText); + } + } + + /** + * Hides soft keyboard. + * + * @param editText EditText which has focus + */ + public void hideSoftKeyboard(EditText editText) { + if (editText == null) + return; + InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + + /** + * Shows soft keyboard. + * + * @param editText EditText which has focus + */ + public void showSoftKeyboard(EditText editText) { + if (editText == null) + return; + InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE); + imm.showSoftInput(editText, 0); + } + + + /** + * Sets focus on a specific EditText field. + * + * @param editText EditText to set focus on + */ + public static void setFocus(EditText editText) { + if (editText == null) + return; + editText.setFocusable(true); + editText.setFocusableInTouchMode(true); + editText.requestFocus(); + } + + /** + * Sets user_default_image PIN background. + * + * @param editText edit text to change + */ + private void setDefaultPinBackground(EditText editText) { + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP && editText instanceof AppCompatEditText) { + editText.setBackgroundTintList + (ContextCompat.getColorStateList(this, R.color.colorAccent)); + } else { + ViewCompat.setBackgroundTintList(editText, ContextCompat.getColorStateList(this, R.color.colorAccent)); + } + } + + /** + * Sets focused PIN field background. + * + * @param editText edit text to change + */ + private void setFocusedPinBackground(EditText editText) { + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP && editText instanceof AppCompatEditText) { + editText.setBackgroundTintList + (ContextCompat.getColorStateList(this, R.color.Red)); + } else { + ViewCompat.setBackgroundTintList(editText, ContextCompat.getColorStateList(this, R.color.Red)); + } + } + + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + } + + @Override + public void onTextChanged(CharSequence s, int i, int i1, int i2) { + + setDefaultPinBackground(pinFirstDigitEditText); + setDefaultPinBackground(pinSecondDigitEditText); + setDefaultPinBackground(pinThirdDigitEditText); + setDefaultPinBackground(pinFourthDigitEditText); + setDefaultPinBackground(pinFifthDigitEditText); + setDefaultPinBackground(pinSixthDigitEditText); + + if (s.length() == 0) { + setFocusedPinBackground(pinFirstDigitEditText); + pinFirstDigitEditText.setText(""); + pinSecondDigitEditText.setText(""); + pinThirdDigitEditText.setText(""); + pinFourthDigitEditText.setText(""); + pinFifthDigitEditText.setText(""); + pinSixthDigitEditText.setText(""); + } else if (s.length() == 1) { + setFocusedPinBackground(pinSecondDigitEditText); + pinFirstDigitEditText.setText(String.valueOf(s.charAt(0))); + pinSecondDigitEditText.setText(""); + pinThirdDigitEditText.setText(""); + pinFourthDigitEditText.setText(""); + pinFifthDigitEditText.setText(""); + pinSixthDigitEditText.setText(""); + } else if (s.length() == 2) { + setFocusedPinBackground(pinThirdDigitEditText); + pinSecondDigitEditText.setText(String.valueOf(s.charAt(1))); + pinThirdDigitEditText.setText(""); + pinFourthDigitEditText.setText(""); + pinFifthDigitEditText.setText(""); + pinSixthDigitEditText.setText(""); + } else if (s.length() == 3) { + setFocusedPinBackground(pinFourthDigitEditText); + pinThirdDigitEditText.setText(String.valueOf(s.charAt(2))); + pinFourthDigitEditText.setText(""); + pinFifthDigitEditText.setText(""); + pinSixthDigitEditText.setText(""); + } else if (s.length() == 4) { + setFocusedPinBackground(pinFifthDigitEditText); + pinFourthDigitEditText.setText(String.valueOf(s.charAt(3))); + pinFifthDigitEditText.setText(""); + pinSixthDigitEditText.setText(""); + } else if (s.length() == 5) { + setFocusedPinBackground(pinSixthDigitEditText); + pinFifthDigitEditText.setText(String.valueOf(s.charAt(4))); + pinSixthDigitEditText.setText(""); + } else if (s.length() == 6) { + pinSixthDigitEditText.setText(String.valueOf(s.charAt(5))); + hideSoftKeyboard(pinSixthDigitEditText); + } + } + + @Override + public void afterTextChanged(Editable editable) { + } + + @Override + public void messageReceived(String messageText) { + String[] words = messageText.split(" "); + String otp = words[8]; + pinHiddenEditText.setText(otp); + pinHiddenEditText.setSelection(pinHiddenEditText.getText().length()); + pinFirstDigitEditText.setText(String.valueOf(otp.charAt(0))); + pinSecondDigitEditText.setText(String.valueOf(otp.charAt(1))); + pinThirdDigitEditText.setText(String.valueOf(otp.charAt(2))); + pinFourthDigitEditText.setText(String.valueOf(otp.charAt(3))); + pinFifthDigitEditText.setText(String.valueOf(otp.charAt(4))); + pinSixthDigitEditText.setText(String.valueOf(otp.charAt(5))); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/WelcomeActivity.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/WelcomeActivity.java new file mode 100644 index 0000000..a49e630 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/WelcomeActivity.java @@ -0,0 +1,224 @@ +package com.sdsmdg.bookshareapp.BSA.ui; + +import android.content.Intent; +import android.graphics.Color; +import android.os.Build; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.ui.fragments.TutorialFragment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class WelcomeActivity extends FragmentActivity { + + private ViewPager pager; + private TextView skipTextView, nextTextView; + private ImageView dot1, dot2, dot3, dot4; + private ImageView[] dots; + private TutorialPagerAdapter tutorialPagerAdapter; + private List titleList, descriptionList; + private List logoIdList; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Making display screen full window + if (Build.VERSION.SDK_INT >= 21) { + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } + + setContentView(R.layout.activity_welcome); + changeStatusBarColor(); + initViews(); + regListeners(); + formLists(); + setBottomDots(0); + pager.setAdapter(tutorialPagerAdapter); + pager.addOnPageChangeListener(viewPagerPageChangeListener); + } + + /** + * to change the color of dots appropriately + * @param i the current position of the viewpager + */ + private void setBottomDots(int i) { + for (int j = 0; j < 4; j++){ + dots[j].setImageResource(R.drawable.normal_dot); + } + dots[i].setImageResource(R.drawable.current_page_dot); + } + + /** + * Making status bar transparent + */ + private void changeStatusBarColor() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Window window = getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(Color.TRANSPARENT); + } + } + + /** + * initialise the various views + */ + private void initViews() { + pager = (ViewPager) findViewById(R.id.tutorial_pager); + skipTextView = (TextView) findViewById(R.id.skip_button); + nextTextView = (TextView) findViewById(R.id.next_button); + dot1 = (ImageView) findViewById(R.id.image_dot_1); + dot2 = (ImageView) findViewById(R.id.image_dot_2); + dot3 = (ImageView) findViewById(R.id.image_dot_3); + dot4 = (ImageView) findViewById(R.id.image_dot_4); + dots = new ImageView[4]; + dots[0] = dot1; + dots[1] = dot2; + dots[2] = dot3; + dots[3] = dot4; + tutorialPagerAdapter = new TutorialPagerAdapter(getSupportFragmentManager()); + titleList = new ArrayList<>(); + descriptionList = new ArrayList<>(); + logoIdList = new ArrayList<>(); + } + + /** + * register listeners for the views + */ + private void regListeners() { + skipTextView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + launchHomeScreen(); + } + }); + nextTextView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + int current = getItem(); + if (current < 3){ + pager.setCurrentItem(current + 1); + } else{ + launchHomeScreen(); + } + } + }); + for (int i = 0; i < 4; i++) { + final int finalI = i; + dots[i].setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + pager.setCurrentItem(finalI); + } + }); + } + } + + /** + * form the various lists for the fragments + */ + private void formLists() { + // form the list containing all the titles. + titleList = Arrays.asList(getResources().getStringArray(R.array.title_list)); + // form the list containing all the descriptions. + descriptionList = Arrays.asList(getResources().getStringArray(R.array.description_list)); + // form the list containing all the logos. + logoIdList.add(R.drawable.campus_books_group); + logoIdList.add(R.drawable.add_books_group); + logoIdList.add(R.drawable.notification_group); + logoIdList.add(R.drawable.user_search_group); + } + + /** + * viewpager change listener + */ + ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() { + @Override + public void onPageSelected(int position) { + setBottomDots(position); + // changing the next button text 'NEXT' / 'LET'S BEGIN' + if (position == 3) { + // last page. make button text to LET'S BEGIN + nextTextView.setText(getResources().getString(R.string.lets_begin)); + skipTextView.setVisibility(View.GONE); + } else { + // still pages are left + nextTextView.setText(getResources().getString(R.string.next)); + skipTextView.setVisibility(View.VISIBLE); + } + } + @Override + public void onPageScrolled(int arg0, float arg1, int arg2) { + } + @Override + public void onPageScrollStateChanged(int arg0) { + } + }; + + /** + * method to launch home screen + */ + private void launchHomeScreen() { + if (getIntent().getExtras() != null) { + String intentData = (String) getIntent().getExtras().get("data_splash"); + if (intentData != null){ + Intent intent = new Intent(WelcomeActivity.this, MainActivity.class); + intent.putExtra("data_splash", intentData); + startActivity(intent); + finish(); + }else { + intentData = (String) getIntent().getExtras().get("toast_message"); + if (intentData != null) { + Toast.makeText(WelcomeActivity.this, intentData, Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(WelcomeActivity.this, LoginActivity.class); + startActivity(intent); + finish(); + } + } + }else { + Intent i = new Intent(getApplicationContext(), LoginActivity.class); + startActivity(i); + finish(); + } + } + + /** + * return the current item of the pager adapter + * @return position of the item + */ + private int getItem() { + return pager.getCurrentItem(); + } + + private class TutorialPagerAdapter extends FragmentPagerAdapter{ + + private TutorialPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + return TutorialFragment.newInstance(titleList.get(position), descriptionList.get(position), + logoIdList.get(position)); + } + + @Override + public int getCount() { + return 4; + } + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/GR/BooksAdapterGR.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/GR/BooksAdapterGR.java new file mode 100644 index 0000000..b4bf9f1 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/GR/BooksAdapterGR.java @@ -0,0 +1,212 @@ +package com.sdsmdg.bookshareapp.BSA.ui.adapter.GR; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.support.annotation.NonNull; +import android.support.v7.app.AlertDialog; +import android.view.ContextThemeWrapper; +import android.support.v7.widget.RecyclerView; +import android.text.Html; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.RatingBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.BooksAPI; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.BookDescription; +import com.sdsmdg.bookshareapp.BSA.api.models.GoodreadsResponse2; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookAddDeleteResponse; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; +import com.squareup.picasso.Picasso; + +import java.text.DecimalFormat; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class BooksAdapterGR extends RecyclerView.Adapter { + + private Context context; + private List bookList; + private Book tempValues = null; + private BookDescription tempDescp; + private String description; + private String token; + private SharedPreferences prefs; + + private final OnItemClickListener listener; + + public interface OnItemClickListener { + void onItemClick(com.sdsmdg.bookshareapp.BSA.api.models.Book book); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + TextView titleBook; + TextView authorBook; + ImageView imageBook; + RatingBar ratingBook; + TextView ratingCount; + public Button add; + + Context context; + + ViewHolder(View v, Context context) { + super(v); + titleBook = (TextView) v.findViewById(R.id.row_books_title); + authorBook = (TextView) v.findViewById(R.id.row_books_author); + imageBook = (ImageView) v.findViewById(R.id.row_books_imageView); + ratingBook = (RatingBar) v.findViewById(R.id.row_books_rating); + ratingCount = (TextView) v.findViewById(R.id.row_books_ratings_count); + add = (Button) v.findViewById(R.id.add); + + this.context = context; + } + + } + + public BooksAdapterGR(Context context, List bookList, OnItemClickListener listener) { + this.bookList = bookList; + this.context = context; + this.listener = listener; + prefs = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.row_books_add, parent, false); + + return new ViewHolder(v, context); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, final int position) { + final String email, title, author, gr_id, gr_img_url; + final Integer search_id; + final Long ratingsCount; + final Float rating; + token = prefs.getString("token", null); + + holder.add.setEnabled(true); + tempValues = bookList.get(position); + holder.titleBook.setText(tempValues.getBookDetails().getTitle()); + holder.authorBook.setText(tempValues.getBookDetails().getAuthor().getAuthor_name()); + Picasso.with(this.context).load(tempValues.getBookDetails().getImage_url()).into(holder.imageBook); + holder.ratingBook.setRating(tempValues.getRating()); + + DecimalFormat formatter = new DecimalFormat("#,###,###"); + + String rating_count = formatter.format(tempValues.getRatingCount()); + + holder.ratingCount.setText("(" + rating_count + ")"); + title = tempValues.getBookDetails().getTitle(); + email = Helper.getUserEmail(); + author = tempValues.getBookDetails().getAuthor().getAuthor_name(); + gr_img_url = tempValues.getBookDetails().getImage_url(); + rating = tempValues.getRating(); + ratingsCount = tempValues.getRatingCount(); + gr_id = tempValues.getId().toString(); + search_id = tempValues.getBookDetails().getId(); + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onItemClick(bookList.get(position)); + } + }); + + holder.add.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + BooksAPI api = NetworkingFactory.getGRInstance().getBooksApi(); + Call call = api.getBookDescription(search_id, CommonUtilities.API_KEY); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.body() != null) { + tempDescp = response.body().getbDesc(); + description = tempDescp.getBDescription(); + + description = Html.fromHtml(description).toString(); + if (description.length() > 1000) { + description = description.substring(0, 990) + "..."; + } + } else { + description = "No Description Available"; + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + description = "No Description Available"; + } + }); + + AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.AppTheme_Dialog)); + builder.setTitle("Do you want to add this Book?"); + builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call addBook = usersAPI.addBook(email, title, author, gr_id, ratingsCount, rating, gr_img_url, description, "Token " + token); + addBook.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + try { + if (response.body() != null) { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + holder.add.setEnabled(false); + holder.add.setTextColor(Color.argb(255, 179, 179, 179)); + } else { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + } + } catch (NullPointerException n) { + Toast.makeText(context, "Sorry, this book can't be added", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Toast.makeText(context, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + }); + builder.setNegativeButton("No", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + builder.show(); + } + }); + } + + @Override + public int getItemCount() { + if (bookList != null) + return bookList.size(); + + return 0; + } + + @Override + public long getItemId(int position) { + return 0; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/GR/BooksAdapterToRead.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/GR/BooksAdapterToRead.java new file mode 100644 index 0000000..26bca5c --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/GR/BooksAdapterToRead.java @@ -0,0 +1,115 @@ +package com.sdsmdg.bookshareapp.BSA.ui.adapter.GR; + +import android.content.Context; +import android.content.Intent; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.RatingBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.models.BookDetailsToRead; +import com.sdsmdg.bookshareapp.BSA.ui.MainActivity; +import com.sdsmdg.bookshareapp.BSA.ui.SearchResultsActivity; +import com.squareup.picasso.Picasso; + +import java.text.DecimalFormat; +import java.util.List; + +public class BooksAdapterToRead extends RecyclerView.Adapter { + + private Context context; + private List bookDetailsToReads; + private BookDetailsToRead tempValues = null; + private final OnItemClickListener listener; + + public interface OnItemClickListener { + void onItemClick(BookDetailsToRead book); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + TextView titleBook; + TextView authorBook; + ImageView imageBook; + RatingBar ratingBook; + TextView ratingCount; + TextView link; + Context context; + + ViewHolder(View v, Context context) { + super(v); + titleBook = (TextView) v.findViewById(R.id.row_books_title); + authorBook = (TextView) v.findViewById(R.id.row_books_author); + imageBook = (ImageView) v.findViewById(R.id.row_books_imageView); + ratingBook = (RatingBar) v.findViewById(R.id.row_books_rating); + ratingCount = (TextView) v.findViewById(R.id.row_books_ratings_count); + link = (TextView) v.findViewById(R.id.directSearch); + this.context = context; + } + + } + + public BooksAdapterToRead(Context context, List bookDetailsToReadList, OnItemClickListener listener) { + this.bookDetailsToReads = bookDetailsToReadList; + this.context = context; + this.listener = listener; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.row_books_simple, parent, false); + ViewHolder vh = new ViewHolder(v, context); + return vh; + } + + @Override + public void onBindViewHolder(final ViewHolder holder, final int position) { + + tempValues = bookDetailsToReads.get(position); + + holder.titleBook.setText(tempValues.getTitle()); + holder.authorBook.setText(tempValues.getAuthor().getAuthors().getAuthor_name()); + if (!tempValues.getImage_url().isEmpty()) { + Picasso.with(this.context).load(tempValues.getImage_url()).placeholder(R.drawable.default_book_image).into(holder.imageBook); + } + holder.ratingBook.setRating(tempValues.getRating()); + DecimalFormat formatter = new DecimalFormat("#,###,###"); + String rating_count = formatter.format(Long.parseLong(tempValues.getRatingCount().toString())); + holder.ratingCount.setText("(" + rating_count + ")"); + + holder.link.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + String searchItem = holder.titleBook.getText().toString(); + + //Toast.makeText(context, searchItem, Toast.LENGTH_SHORT).show(); + + Intent intent = new Intent(context, MainActivity.class); + intent.putExtra("pass_it_on", searchItem); + context.startActivity(intent); + + } + }); + + } + + @Override + public int getItemCount() { + if (bookDetailsToReads != null) + return bookDetailsToReads.size(); + + return 0; + } + + @Override + public long getItemId(int position) { + return 0; + } + +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BookAdapter.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BookAdapter.java new file mode 100644 index 0000000..9e0babd --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BookAdapter.java @@ -0,0 +1,519 @@ +package com.sdsmdg.bookshareapp.BSA.ui.adapter.Local; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.support.v4.content.ContextCompat; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; +import android.util.Log; +import android.util.SparseBooleanArray; +import android.view.ActionMode; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RatingBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.BookAddDeleteResponse; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.RemoveBook; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.ui.MyProfile; +import com.squareup.picasso.Picasso; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class BookAdapter extends RecyclerView.Adapter { + + private static final int PENDING_REMOVAL_TIMEOUT = 1500; + private Book tempValues = null; + private List itemsPendingRemoval; + private String userId; + private Context context; + private List bookList; + private List selectedBookList = new ArrayList<>(); + private ActionMode mActionMode; + private SharedPreferences prefs; + private boolean undoOn = true; + private boolean isMultiSelect = false; + private List booksToDelete = new ArrayList<>(); + + /** + * is undo on, you can turn it on from the toolbar menu + * this array stores whether the current book is selected or not + */ + //This activity reference is required to activate the contextual action bar + private Activity activity; + + private Handler handler = new Handler(); // handler for running delayed runnables + private HashMap pendingRunnables = new HashMap<>(); // map of items to pending runnables, so we can cancel a removal if need be + + public BookAdapter(Context context, String userId, List bookList, Activity activity) { + itemsPendingRemoval = new ArrayList<>(); + this.bookList = bookList; + this.userId = userId; + this.context = context; + this.activity = activity; + prefs = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + } + + class ViewHolder extends RecyclerView.ViewHolder { + + LinearLayout bookLayout, deleteLayout; + TextView titleBook; + TextView authorBook; + ImageView imageBook; + RatingBar ratingBook; + TextView ratingCount; + Button undoButton; + + ViewHolder(View itemView) { + super(itemView); + bookLayout = (LinearLayout) itemView.findViewById(R.id.book_layout); + deleteLayout = (LinearLayout) itemView.findViewById(R.id.delete_layout); + titleBook = (TextView) itemView.findViewById(R.id.book_title); + authorBook = (TextView) itemView.findViewById(R.id.author); + imageBook = (ImageView) itemView.findViewById(R.id.book_cover); + ratingBook = (RatingBar) itemView.findViewById(R.id.book_rating); + ratingCount = (TextView) itemView.findViewById(R.id.ratings_count); + undoButton = (Button) itemView.findViewById(R.id.undo_button); + } + } + + //This function is used to delete the selected items + private void deleteSelectedItem() { + booksToDelete.addAll(selectedBookList); + notifyDataSetChanged(); + for (Book book : selectedBookList) { + remove(book); + } + } + + //This method is called after the contextual action bar is disabled + public void reset() { + isMultiSelect = false; + selectedBookList = new ArrayList<>(); + notifyDataSetChanged(); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_mybooks, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + final ViewHolder viewHolder = holder; + final Book rbook = bookList.get(position); + + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (isMultiSelect){ + multiSelect(viewHolder.getAdapterPosition()); + } + } + }); + + viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (!isMultiSelect) { + isMultiSelect = true; + if (mActionMode == null) { + mActionMode = activity.startActionMode(mActionModeCallback); + } + } + multiSelect(viewHolder.getAdapterPosition()); + return true; + } + }); + if (booksToDelete.contains(rbook)){ + viewHolder.bookLayout.setAlpha(0.25f); + viewHolder.deleteLayout.setVisibility(View.VISIBLE); + viewHolder.itemView.setOnLongClickListener(null); + }else{ + viewHolder.bookLayout.setAlpha(1f); + viewHolder.deleteLayout.setVisibility(View.GONE); + viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (!isMultiSelect) { + isMultiSelect = true; + if (mActionMode == null) { + mActionMode = activity.startActionMode(mActionModeCallback); + } + } + multiSelect(viewHolder.getAdapterPosition()); + return true; + } + }); + } + if (itemsPendingRemoval.contains(rbook)) { + // we need to show the "undo" state of the row + viewHolder.itemView.setBackgroundColor(context.getResources().getColor(R.color.delete2)); + viewHolder.titleBook.setVisibility(View.INVISIBLE); + viewHolder.authorBook.setText("Delete Book ?"); + viewHolder.authorBook.setTextSize(20); + viewHolder.ratingCount.setVisibility(View.INVISIBLE); + viewHolder.ratingBook.setVisibility(View.INVISIBLE); + viewHolder.imageBook.setVisibility(View.INVISIBLE); + viewHolder.undoButton.setVisibility(View.VISIBLE); + viewHolder.undoButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // user wants to undo the removal, let's cancel the pending task + Runnable pendingRemovalRunnable = pendingRunnables.get(rbook); + pendingRunnables.remove(rbook); + if (pendingRemovalRunnable != null) + handler.removeCallbacks(pendingRemovalRunnable); + itemsPendingRemoval.remove(rbook); + // this will rebind the row in "normal" state + notifyItemChanged(bookList.indexOf(rbook)); + } + }); + + } else { + // we need to show the "normal" state + tempValues = bookList.get(position); + viewHolder.titleBook.setText(tempValues.getTitle()); + viewHolder.authorBook.setTextSize(14); + viewHolder.authorBook.setText(tempValues.getAuthor()); + if (!tempValues.getGrImgUrl().isEmpty()) { + Picasso.with(context).load(tempValues.getGrImgUrl()).placeholder(R.drawable.default_book_image).into(viewHolder.imageBook); + } + viewHolder.ratingBook.setRating(tempValues.getRating()); + viewHolder.ratingCount.setText("(" + tempValues.getRatingsCount() + ")"); + //if the book is selected, change it's color to holo blue light + if (selectedBookList.contains(bookList.get(position))){ + viewHolder.itemView.setBackgroundColor(ContextCompat.getColor(context, R.color.delete_gray)); + }else{ + viewHolder.itemView.setBackgroundColor(ContextCompat.getColor(context, R.color.White)); + } + viewHolder.titleBook.setVisibility(View.VISIBLE); + viewHolder.authorBook.setVisibility(View.VISIBLE); + viewHolder.ratingBook.setVisibility(View.VISIBLE); + viewHolder.ratingCount.setVisibility(View.VISIBLE); + viewHolder.imageBook.setVisibility(View.VISIBLE); + viewHolder.undoButton.setVisibility(View.GONE); + viewHolder.undoButton.setOnClickListener(null); + } + } + + private void multiSelect(int adapterPosition) { + if (mActionMode != null){ + if (selectedBookList.contains(bookList.get(adapterPosition))){ + selectedBookList.remove(bookList.get(adapterPosition)); + } else { + selectedBookList.add(bookList.get(adapterPosition)); + } + if (selectedBookList.size() > 1) { + mActionMode.setTitle(selectedBookList.size() + " items selected"); + } else if (selectedBookList.size() > 0) { + mActionMode.setTitle(selectedBookList.size() + " item selected"); + } else { + mActionMode.finish(); + } + notifyDataSetChanged(); + } + } + + @Override + public int getItemCount() { + if (bookList != null) + return bookList.size(); + + return 0; + } + + private boolean isUndoOn() { + return undoOn; + } + + private void pendingRemoval(int position) { + final Book rbook = bookList.get(position); + + if (!itemsPendingRemoval.contains(rbook)) { + itemsPendingRemoval.add(rbook); + // this will redraw row in "undo" state + notifyDataSetChanged(); + // let's create, store and post a runnable to remove the item + Runnable pendingRemovalRunnable = new Runnable() { + @Override + public void run() { + booksToDelete.add(rbook); + notifyDataSetChanged(); + remove(rbook); + } + }; + handler.postDelayed(pendingRemovalRunnable, PENDING_REMOVAL_TIMEOUT); + pendingRunnables.put(rbook, pendingRemovalRunnable); + } + } + + private void remove(Book rbook) { + removeBook(rbook.getId(), rbook); + } + + private void removeBook(final String bookId, final Book rbook) { + + RemoveBook removeBook = new RemoveBook(); + removeBook.setBookId(bookId); + removeBook.setUserId(userId); + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call call = usersAPI.removeBook(removeBook, "Token " + prefs.getString("token", null)); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + String detail = response.body().getDetail(); + Toast.makeText(context, detail, Toast.LENGTH_SHORT).show(); + if (detail.equals("Successfully Removed!!")) { + //Make corresponding changes in MyProfile activity when a book is removed + ((MyProfile)context).onBookRemoved(); + booksToDelete.remove(rbook); + if (itemsPendingRemoval.contains(rbook)) { + itemsPendingRemoval.remove(rbook); + } + if (bookList.contains(rbook)) { + bookList.remove(rbook); + } + } + } + notifyDataSetChanged(); + } + + @Override + public void onFailure(Call call, Throwable t) { + itemsPendingRemoval.remove(rbook); + booksToDelete.remove(rbook); + //This line will remove the undo button and show the book row completely + notifyDataSetChanged(); + Log.i("book_size", Integer.toString(bookList.size())); + Toast.makeText(context, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + + private boolean isPendingRemoval(int position) { + Book rbook = bookList.get(position); + return itemsPendingRemoval.contains(rbook); + } + + + private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { + + // Called when the action mode is created; startActionMode() was called + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + // Inflate a menu resource providing context menu items + MenuInflater inflater = mode.getMenuInflater(); + inflater.inflate(R.menu.contextual_menu, menu); + return true; + } + + // Called each time the action mode is shown. Always called after onCreateActionMode, but + // may be called multiple times if the mode is invalidated. + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; // Return false if nothing is done + } + + // Called when the user selects a contextual menu item + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_delete: + deleteSelectedItem(); + mode.finish(); // Action picked, so close the CAB + return true; + default: + return false; + } + } + + // Called when the user exits the action mode + @Override + public void onDestroyActionMode(ActionMode mode) { + reset(); + mActionMode = null; + } + }; + + public void setUpItemTouchHelper(RecyclerView mRecyclerView) { + + ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) { + + // we want to cache these and not allocate anything repeatedly in the onChildDraw method + Drawable background; + Drawable xMark; + int xMarkMargin; + boolean initiated; + + private void init() { + background = new ColorDrawable(context.getResources().getColor(R.color.delete2)); + xMark = ContextCompat.getDrawable(context, R.drawable.ic_clear_24dp); + xMark.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP); + xMarkMargin = (int) context.getResources().getDimension(R.dimen.ic_clear_margin); + initiated = true; + } + + // not important, we don't want drag & drop + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { + return false; + } + + @Override + public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + int position = viewHolder.getAdapterPosition(); + // BookAdapter bookAdapter = (BookAdapter) recyclerView.getAdapter(); + if (isUndoOn() && isPendingRemoval(position)) { + return 0; + } + return super.getSwipeDirs(recyclerView, viewHolder); + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) { + int swipedPosition = viewHolder.getAdapterPosition(); + // BookAdapter adapter = (BookAdapter) mRecyclerView.getAdapter(); + boolean undoOn = isUndoOn(); + if (undoOn) { + pendingRemoval(swipedPosition); + } + } + + @Override + public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + View itemView = viewHolder.itemView; + + if (viewHolder.getAdapterPosition() == -1) { + // not interested in those + return; + } + + if (!initiated) { + init(); + } + + // draw red background + background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + background.draw(c); + + // draw x mark + int itemHeight = itemView.getBottom() - itemView.getTop(); + int intrinsicWidth = xMark.getIntrinsicWidth(); + int intrinsicHeight = xMark.getIntrinsicWidth(); + + int xMarkLeft = itemView.getRight() - xMarkMargin - intrinsicWidth; + int xMarkRight = itemView.getRight() - xMarkMargin; + int xMarkTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2; + int xMarkBottom = xMarkTop + intrinsicHeight; + xMark.setBounds(xMarkLeft, xMarkTop, xMarkRight, xMarkBottom); + + xMark.draw(c); + + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + } + + }; + ItemTouchHelper mItemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback); + mItemTouchHelper.attachToRecyclerView(mRecyclerView); + } + + public void setUpAnimationDecoratorHelper(RecyclerView mRecyclerView) { + mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() { + + // we want to cache this and not allocate anything repeatedly in the onDraw method + Drawable background; + boolean initiated; + + private void init() { + background = new ColorDrawable(context.getResources().getColor(R.color.delete2)); + initiated = true; + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + + if (!initiated) { + init(); + } + + // only if animation is in progress + if (parent.getItemAnimator().isRunning()) { + + View lastViewComingDown = null; + View firstViewComingUp = null; + + // this is fixed + int left = 0; + int right = parent.getWidth(); + + // this we need to find out + int top = 0; + int bottom = 0; + + // find relevant translating views + int childCount = parent.getLayoutManager().getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = parent.getLayoutManager().getChildAt(i); + if (child.getTranslationY() < 0) { + // view is coming down + lastViewComingDown = child; + } else if (child.getTranslationY() > 0) { + // view is coming up + if (firstViewComingUp == null) { + firstViewComingUp = child; + } + } + } + + if (lastViewComingDown != null && firstViewComingUp != null) { + // views are coming down AND going up to fill the void + top = lastViewComingDown.getBottom() + (int) lastViewComingDown.getTranslationY(); + bottom = firstViewComingUp.getTop() + (int) firstViewComingUp.getTranslationY(); + } else if (lastViewComingDown != null) { + // views are going down to fill the void + top = lastViewComingDown.getBottom() + (int) lastViewComingDown.getTranslationY(); + bottom = lastViewComingDown.getBottom(); + } else if (firstViewComingUp != null) { + // views are coming up to fill the void + top = firstViewComingUp.getTop(); + bottom = firstViewComingUp.getTop() + (int) firstViewComingUp.getTranslationY(); + } + + background.setBounds(left, top, right, bottom); + background.draw(c); + + } + super.onDraw(c, parent, state); + } + }); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BooksAdapterRequest.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BooksAdapterRequest.java new file mode 100644 index 0000000..31f875f --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BooksAdapterRequest.java @@ -0,0 +1,212 @@ +package com.sdsmdg.bookshareapp.BSA.ui.adapter.Local; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.RatingBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.Notification.Notifications; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; +import com.squareup.picasso.Picasso; + +import java.text.DecimalFormat; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class BooksAdapterRequest extends RecyclerView.Adapter { + + private Context context; + private List bookList; + Book tempValues = null; + SharedPreferences prefs; + + String userId; + private final OnItemClickListener listener; + + List cancels; + + public interface OnItemClickListener { + public void onItemClick(Book book); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + public TextView titleBook; + public TextView authorBook; + public ImageView imageBook; + public RatingBar ratingBook; + public TextView ratingCount; + public Button request; + Context context; + + public ViewHolder(View v, Context context) { + super(v); + titleBook = (TextView) v.findViewById(R.id.row_books_title); + authorBook = (TextView) v.findViewById(R.id.row_books_author); + imageBook = (ImageView) v.findViewById(R.id.row_books_imageView); + ratingBook = (RatingBar) v.findViewById(R.id.row_books_rating); + ratingCount = (TextView) v.findViewById(R.id.row_books_ratings_count); + request = (Button) v.findViewById(R.id.requestButton); + this.context = context; + } + + } + + public BooksAdapterRequest(Context context, List bookList, OnItemClickListener listener, String userId) { + this.bookList = bookList; + this.context = context; + this.listener = listener; + this.userId = userId; + prefs = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.row_books_request, parent, false); + ViewHolder vh = new ViewHolder(v, context); + return vh; + } + + @Override + public void onBindViewHolder(final ViewHolder holder, final int position) { + final String bookTitle, bookId; + tempValues = bookList.get(position); + bookId = tempValues.getId(); + bookTitle = tempValues.getTitle(); + holder.titleBook.setText(tempValues.getTitle()); + holder.authorBook.setText(tempValues.getAuthor()); + + if (cancels.get(position)) { + holder.request.setText("Cancel"); + } else { + holder.request.setText("Request"); + } + + if (!tempValues.getGrImgUrl().isEmpty()) { + Picasso.with(this.context).load(tempValues.getGrImgUrl()).placeholder(R.drawable.default_book_image).into(holder.imageBook); + } + + holder.ratingBook.setRating(tempValues.getRating()); + DecimalFormat formatter = new DecimalFormat("#,###,###"); + String rating_count = formatter.format(tempValues.getRatingsCount()); + holder.ratingCount.setText("(" + rating_count + ")"); + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onItemClick(bookList.get(position)); + } + }); + + holder.request.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + if (!cancels.get(position)) { + builder.setTitle("Do you want to send a request?"); + } else { + builder.setTitle("Do you want to cancel the request?"); + } + builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if(holder.request.getText().equals("Request")) { + String process = "request"; + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call sendNotif = usersAPI.sendNotif(Helper.getUserId(), Helper.getUserName(), bookId, bookTitle, process, userId, "request for", "Token " + prefs + .getString("token", null)); + sendNotif.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + holder.request.setText("Cancel"); + } else { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(context, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } else { + + String process = "cancel"; + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call cancelNotif = usersAPI.cancelNotif(bookId, userId, process, "Token " + prefs + .getString("token", null)); + cancelNotif.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + holder.request.setText("Request"); + + } else { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(context, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + } + }); + + builder.setNegativeButton("No", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + + builder.show(); + + } + }); + + + } + + public void setCancels(List cancels) { + this.cancels = cancels; + } + + @Override + public int getItemCount() { + if (bookList != null) + return bookList.size(); + + return 0; + } + + @Override + public long getItemId(int position) { + return 0; + } + +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BooksAdapterSimple.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BooksAdapterSimple.java new file mode 100644 index 0000000..4cd736d --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/BooksAdapterSimple.java @@ -0,0 +1,130 @@ +package com.sdsmdg.bookshareapp.BSA.ui.adapter.Local; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.RatingBar; +import android.widget.TextView; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalBooks.Book; +import com.squareup.picasso.Picasso; + +import java.text.DecimalFormat; +import java.util.List; + +public class BooksAdapterSimple extends RecyclerView.Adapter { + + private static final int VIEW_TYPE_LOADING = 123; + private Context context; + private List bookList; + Book tempValues = null; + private final OnItemClickListener listener; + private int totalCount = 0; + + public interface OnItemClickListener { + public void onItemClick(Book book); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + public TextView titleBook; + public TextView authorBook; + public ImageView imageBook; + public RatingBar ratingBook; + public TextView ratingCount; + public TextView link; + Context context; + + public ViewHolder(View v, Context context) { + super(v); + titleBook = (TextView) v.findViewById(R.id.row_books_title); + authorBook = (TextView) v.findViewById(R.id.row_books_author); + imageBook = (ImageView) v.findViewById(R.id.row_books_imageView); + ratingBook = (RatingBar) v.findViewById(R.id.row_books_rating); + ratingCount = (TextView) v.findViewById(R.id.row_books_ratings_count); + link = (TextView) v.findViewById(R.id.directSearch); + this.context = context; + } + + } + + public BooksAdapterSimple(Context context, List bookList, OnItemClickListener listener) { + this.bookList = bookList; + this.context = context; + this.listener = listener; + } + + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + ViewHolder vh; + if(viewType == VIEW_TYPE_LOADING) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.progress_item, parent, false); + vh = new ViewHolder(v, context); + } else { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.row_books_simple, parent, false); + vh = new ViewHolder(v, context); + } + return vh; + } + + @Override + public void onBindViewHolder(ViewHolder holder, final int position) { + + if(position < bookList.size()) { + tempValues = bookList.get(position); + + holder.titleBook.setText(tempValues.getTitle()); + holder.authorBook.setText(tempValues.getAuthor()); + if (!tempValues.getGrImgUrl().isEmpty()) { + Picasso.with(this.context).load(tempValues.getGrImgUrl()).placeholder(R.drawable.default_book_image).into(holder.imageBook); + } + holder.ratingBook.setRating(tempValues.getRating()); + DecimalFormat formatter = new DecimalFormat("#,###,###"); + String rating_count = formatter.format(tempValues.getRatingsCount()); + holder.ratingCount.setText("(" + rating_count + ")"); + + holder.link.setVisibility(View.GONE); + + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onItemClick(bookList.get(position)); + } + }); + } else { + //It means the progress bar is shown on screen + } + + } + + @Override + public int getItemCount() { + if (bookList != null) + return bookList.size(); + + return 0; + } + + @Override + public int getItemViewType(int position) { + if(position >= bookList.size() && totalCount > bookList.size()) { + return VIEW_TYPE_LOADING; + } + return super.getItemViewType(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/CollegeAdapter.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/CollegeAdapter.java new file mode 100644 index 0000000..a767a73 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/CollegeAdapter.java @@ -0,0 +1,58 @@ +package com.sdsmdg.bookshareapp.BSA.ui.adapter.Local; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.ui.College; + +import java.util.ArrayList; + +/** + * Created by Harshit Bansal on 5/16/2017. + */ + +public class CollegeAdapter extends BaseAdapter { + Context context; + ArrayList collegeArrayList; + LayoutInflater inflater; + + public CollegeAdapter(Context context, ArrayList collegeArrayList) + { + this.context = context; + this.collegeArrayList = collegeArrayList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return collegeArrayList.size(); + } + + @Override + public Object getItem(int position) { + return collegeArrayList.get(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View view = convertView; + view = inflater.inflate(R.layout.college_layout , parent ,false); + TextView name = (TextView) view.findViewById(R.id.text_college); + TextView domain = (TextView) view.findViewById(R.id.text_domain); + name.setText(collegeArrayList.get(position).getCollegeName()); + domain.setText(collegeArrayList.get(position).getCollegeDomain()); + return view; + } +} + diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/NotificationAdapter.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/NotificationAdapter.java new file mode 100644 index 0000000..0ed9612 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/NotificationAdapter.java @@ -0,0 +1,360 @@ +package com.sdsmdg.bookshareapp.BSA.ui.adapter.Local; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.graphics.Typeface; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.RecyclerView; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.Notification.Notifications; +import com.sdsmdg.bookshareapp.BSA.ui.BookDetailsActivity; +import com.sdsmdg.bookshareapp.BSA.ui.UserProfile; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; + +import java.util.ArrayList; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class NotificationAdapter extends RecyclerView.Adapter { + + final String TAG = NotificationAdapter.class.getSimpleName(); + + Context context; + List notificationList = new ArrayList<>(); + Notifications notifications = null; + SharedPreferences prefs; + + + public static class ViewHolder extends RecyclerView.ViewHolder { + public TextView content, timeTextView; + View accept, reject, buttonLayout; + + Context context; + + public ViewHolder(View v, Context context, int viewType) { + super(v); + content = (TextView) v.findViewById(R.id.content); + timeTextView = (TextView) v.findViewById(R.id.time); + buttonLayout = v.findViewById(R.id.button_layout); + + if (viewType == 1) { + accept = v.findViewById(R.id.accept); + reject = v.findViewById(R.id.reject); + } else if (viewType == 2) { + buttonLayout.setVisibility(View.GONE); + } + + this.context = context; + } + } + + public NotificationAdapter(Context context, List list) { + this.context = context; + this.notificationList = list; + prefs = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.row_notification, parent, false); + return new ViewHolder(v, context, viewType); + } + + @Override + public int getItemViewType(int position) { + Notifications notifications = notificationList.get(position); + if (notifications.getMessage().equals("requested for")) { + return 1; + } + return 2; + } + + @Override + public void onBindViewHolder(final ViewHolder holder, final int position) { + + notifications = notificationList.get(position); + + int senderNameLength = notifications.getSenderName().length(); + int bookNameLength = notifications.getBookTitle().length(); + + SpannableString content = null; + final String bookId, notifId, targetId, bookTitle, time; + Long timeDiff, minutes; + Integer days, hours, weeks, months; + + timeDiff = System.currentTimeMillis() / 1000 - notifications.getUnix_time(); + minutes = timeDiff / 60; + hours = minutes.intValue() / 60; + days = hours / 24; + weeks = days / 7; + months = weeks / 4; + + if(timeDiff<0){ + timeDiff = Long.parseLong("0"); + } + + if (timeDiff < 60) { + if (timeDiff == 1) { + time = " " + timeDiff.toString() + " second ago"; + } else { + time = " " + timeDiff.toString() + " seconds ago"; + } + } else { + if (minutes < 60) { + if (minutes == 1) { + time = " " + minutes.toString() + " minute ago"; + } else { + time = " " + minutes.toString() + " minutes ago"; + } + + + } else { + if (hours < 25) { + if (hours == 1) { + time = " " + hours.toString() + " hour ago"; + + } else { + time = " " + hours.toString() + " hours ago"; + + } + + } else { + if (days == 1) { + time = " " + days.toString() + " day ago"; + + } else { + if (days < 7) { + time = " " + days.toString() + " days ago"; + } else { + if (weeks == 1) { + time = " " + weeks.toString() + " week ago"; + + } else { + if (months < 1) { + time = " " + weeks.toString() + " weeks ago"; + + } else { + if (months == 1) { + time = " " + months.toString() + " month ago"; + + } else { + time = " " + months.toString() + " months ago"; + + } + } + + } + } + + } + } + } + + } + + + String message = notifications.getMessage(); + + if (message.equals("requested for")) { + bookId = notifications.getBookId(); + bookTitle = notifications.getBookTitle(); + targetId = notifications.getSenderId(); + notifId = notifications.getId(); + + content = new SpannableString(notifications.getSenderName() + " " + message + " " + notifications.getBookTitle()); + content.setSpan(getClickableSpanNameInstance(notifications.getSenderId()), 0, senderNameLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + content.setSpan(getClickableSpanBookInstance(notifications.getBookId()), senderNameLength + message.length() + 2, senderNameLength + message.length() + 2 + bookNameLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holder.timeTextView.setText(time); + + + holder.accept.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + acceptRequest(holder, notifId, bookId, bookTitle, Helper.getUserId(), Helper.getUserName(), targetId, v); + } + }); + + holder.reject.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + rejectRequest(holder, notifId); + } + }); + + } else if (message.equals("You rejected request for")) { + if (!notifications.getSenderId().equals(Helper.getUserId())) { + String localMessage = "You rejected request by "; + content = new SpannableString(localMessage + notifications.getSenderName() + " for " + notifications.getBookTitle()); + content.setSpan(getClickableSpanNameInstance(notifications.getSenderId()), localMessage.length(), localMessage.length() + senderNameLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + content.setSpan(getClickableSpanBookInstance(notifications.getBookId()), localMessage.length() + senderNameLength + 5, localMessage.length() + senderNameLength + 5 + bookNameLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holder.timeTextView.setText(time); + + } + } else if (message.equals("has accepted your request for")) { + content = new SpannableString(notifications.getSenderName() + " " + message + " " + notifications.getBookTitle()); + content.setSpan(getClickableSpanNameInstance(notifications.getSenderId()), 0, senderNameLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + content.setSpan(getClickableSpanBookInstance(notifications.getBookId()), senderNameLength + message.length() + 2, senderNameLength + message.length() + 2 + bookNameLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holder.timeTextView.setText(time); + + } else if (message.equals("You accepted request for")) { + if (!notifications.getSenderId().equals(Helper.getUserId())) { + String localMessage = "You accepted the request by "; + content = new SpannableString(localMessage + notifications.getSenderName() + " for " + notifications.getBookTitle()); + content.setSpan(getClickableSpanNameInstance(notifications.getSenderId()), localMessage.length(), localMessage.length() + senderNameLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + content.setSpan(getClickableSpanBookInstance(notifications.getBookId()), localMessage.length() + senderNameLength + 5, localMessage.length() + senderNameLength + 5 + bookNameLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holder.timeTextView.setText(time); + + } + } + + if (content != null) { + holder.content.setText(content); + holder.content.setMovementMethod(LinkMovementMethod.getInstance()); + holder.timeTextView.setText(time); + + } else { + + } + + } + + private ClickableSpan getClickableSpanNameInstance(final String id) { + return new ClickableSpan() { + @Override + public void onClick(View widget) { + Intent i = new Intent(context, UserProfile.class); + i.putExtra("id", id); + context.startActivity(i); + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + ds.setUnderlineText(false); + ds.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); + ds.setColor(Color.BLACK); + } + }; + } + + private ClickableSpan getClickableSpanBookInstance(final String id) { + return new ClickableSpan() { + @Override + public void onClick(View widget) { + Intent i = new Intent(context, BookDetailsActivity.class); + i.putExtra("id", id); + context.startActivity(i); + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + ds.setUnderlineText(false); + ds.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC)); + ds.setColor(Color.argb(255, 61, 61, 61)); + } + }; + } + + public void acceptRequest(final ViewHolder holder, final String nId, final String bookId, final String bookTitle, final String senderId, final String senderName, final String targetId, final View v) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle("Are you sure you want to accept this request?"); + builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call sendNotif = usersAPI.acceptNotif(nId, senderId, senderName, bookId, bookTitle, "accept", targetId, "accepted request", "Token " + prefs.getString("token", null)); + sendNotif.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + holder.buttonLayout.setVisibility(View.GONE); + } else { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(context, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + }); + builder.setNegativeButton("No", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + builder.show(); + } + + public void rejectRequest(final ViewHolder holder, final String nId) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle("Are you sure you want to reject this request?"); + builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String process = "request"; + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call sendNotif = usersAPI.rejectNotif(nId, "reject", "rejected request", "Token " + prefs.getString("token", null)); + sendNotif.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + holder.buttonLayout.setVisibility(View.GONE); + + } else { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(context, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + + } + }); + builder.setNegativeButton("No", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + builder.show(); + } + + @Override + public int getItemCount() { + if (notificationList != null) + return notificationList.size(); + return 0; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/UsersAdapter.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/UsersAdapter.java new file mode 100644 index 0000000..c2200c4 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/adapter/Local/UsersAdapter.java @@ -0,0 +1,254 @@ +package com.sdsmdg.bookshareapp.BSA.ui.adapter.Local; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.LocalUsers.UserInfo; +import com.sdsmdg.bookshareapp.BSA.api.models.Notification.Notifications; +import com.sdsmdg.bookshareapp.BSA.ui.MyProfile; +import com.sdsmdg.bookshareapp.BSA.ui.UserProfile; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; +import com.squareup.picasso.Picasso; + +import java.util.ArrayList; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class UsersAdapter extends RecyclerView.Adapter { + private Context context; + private List userList; + UserInfo tempValues = null; + private final OnItemClickListener listener; + String bookId, bookTitle; + String userId; + boolean withRequestButton; + SharedPreferences prefs; + List cancels = new ArrayList<>(); + + public interface OnItemClickListener { + void onItemClick(UserInfo userInfo); + } + + @Override + public int getItemViewType(int position) { + if (withRequestButton) { + return 0; + } + return 1; + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + public TextView nameUser; + public TextView emailUser; + public Button request; + public TextView hostelUser; + public ImageView imageUser; + Context context; + + public ViewHolder(View v, Context context, int viewType) { + super(v); + nameUser = (TextView) v.findViewById(R.id.row_user_name); + imageUser = (ImageView) v.findViewById(R.id.row_user_image); + + emailUser = (TextView) v.findViewById(R.id.row_user_email); + hostelUser = (TextView) v.findViewById(R.id.row_user_hostel); + if (viewType == 0) + request = (Button) v.findViewById(R.id.requestButton); + + this.context = context; + } + } + + public UsersAdapter(boolean withRequestButton, String userId, Context context, List userList, String bookTitle, String bookId, OnItemClickListener listener) { + this.userList = userList; + this.context = context; + this.listener = listener; + this.bookTitle = bookTitle; + this.bookId = bookId; + this.userId = userId; + this.withRequestButton = withRequestButton; + prefs = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View v; + if (viewType == 0) { + v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.row_users, parent, false); + } else { + v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.row_users_without_request, parent, false); + } + return new ViewHolder(v, context, viewType); + } + + @Override + public void onBindViewHolder(final ViewHolder holder, final int position) { + final String id; + tempValues = userList.get(position); + id = tempValues.getId(); + + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + listener.onItemClick(userList.get(position)); + Intent i; + if (!userId.equals(id)) {//Open UserProfile if it is not me + i = new Intent(context, UserProfile.class); + i.putExtra("id", id); + } else {//Open MyProfile if it's me + i = new Intent(context, MyProfile.class); + i.putExtra("id", id); + } + context.startActivity(i); + } + }); + + holder.nameUser.setText(tempValues.getName()); + holder.emailUser.setText(tempValues.getEmail()); + holder.hostelUser.setText(tempValues.getHostel()); + //check if it is simple userlist or userlist with request..if yes the display request button.. + if (cancels.size() != 0) { + + if (cancels.get(position)) { + holder.request.setText("Cancel"); + } else { + holder.request.setText("Request"); + } + } + + if (!id.equals(userId)) { + if (withRequestButton) { + holder.request.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + showAlertDialog(holder, id, position); + } + }); + } + } else { + if (withRequestButton) { + holder.request.setVisibility(View.GONE); + } + } + + String url = CommonUtilities.local_books_api_url + "image/" + id + "/"; + Picasso.with(this.context).load(url).placeholder(R.drawable.ic_profile).into(holder.imageUser); + + } + + private void showAlertDialog(final ViewHolder holder, final String id, final int position) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + + if (holder.request.getText() == "Request") { + builder.setTitle("Send request?"); + } else { + builder.setTitle("Cancel request?"); + } + + builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (holder.request.getText().equals("Request")) { + String process = "request"; + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call sendNotif = usersAPI.sendNotif(Helper.getUserId(), Helper.getUserName(), bookId, bookTitle, process, id, "request for", "Token " + prefs.getString("token", null)); + sendNotif.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + holder.request.setText("Cancel"); + + } else { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(context, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } else { + String process = "cancel"; + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call cancelNotif = usersAPI.cancelNotif(bookId, userList.get(position).getId(), process, "Token " + prefs.getString("token", null)); + cancelNotif.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + holder.request.setText("Request"); + + } else { + Toast.makeText(context, response.body().getDetail(), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(context, R.string.connection_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + } + }); + + builder.setNegativeButton("No", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + builder.show(); + } + + public void setBookId(String bookId) { + this.bookId = bookId; + } + + public void setCancels(List cancels) { + this.cancels = cancels; + } + + public void setBookTitle(String bookTitle) { + this.bookTitle = bookTitle; + } + + @Override + public int getItemCount() { + if (userList != null) { + return userList.size(); + } + + return 0; + } + + @Override + public long getItemId(int position) { + return 0; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/BookListFragment.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/BookListFragment.java new file mode 100644 index 0000000..02a346d --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/BookListFragment.java @@ -0,0 +1,109 @@ +package com.sdsmdg.bookshareapp.BSA.ui.fragments; + +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.BooksAPI; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.models.Book; +import com.sdsmdg.bookshareapp.BSA.api.models.GoodreadsResponse; +import com.sdsmdg.bookshareapp.BSA.api.models.Search; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.GR.BooksAdapterGR; + +import java.util.ArrayList; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class BookListFragment extends Fragment { + + public static String resp; + + public static String getResp() { + return resp; + } + + private RecyclerView resultsList; + private ProgressBar progressBar; + List bookList = new ArrayList<>(); + BooksAdapterGR adapter; + private RecyclerView.LayoutManager mLayoutManager; + TextView no_books; + Search sr; + Context context; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.book_list_fragment, container, false); + no_books = (TextView) view.findViewById(R.id.no_books); + progressBar = (ProgressBar) view.findViewById(R.id.indeterminateBar); + no_books.setVisibility(View.GONE); + resultsList = (RecyclerView) view.findViewById(R.id.results_list); + resultsList.setNestedScrollingEnabled(false); + mLayoutManager = new LinearLayoutManager(getActivity()); + resultsList.setLayoutManager(mLayoutManager); + context = getActivity(); + + adapter = new BooksAdapterGR(getActivity(), bookList, new BooksAdapterGR.OnItemClickListener() { + @Override + public void onItemClick(Book book) { + } + }); + resultsList.setAdapter(adapter); + + return view; + } + + public void getBooks(String query, String field, String key) { + + bookList.clear(); + progressBar.setVisibility(View.VISIBLE); + no_books.setVisibility(View.GONE); + resultsList.setVisibility(View.GONE); + + BooksAPI api = NetworkingFactory.getGRInstance().getBooksApi(); + Call call = api.getBooks(query, field, key); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + progressBar.setVisibility(View.GONE); + if (response.body() != null) { + sr = response.body().getSearch(); + bookList.addAll(sr.getBooks()); + adapter.notifyDataSetChanged(); + if (bookList.size() == 0) { + no_books.setVisibility(View.VISIBLE); + }else{ + resultsList.setVisibility(View.VISIBLE); + } + resp = response.toString(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + progressBar.setVisibility(View.GONE); + if (bookList.size() == 0){ + no_books.setVisibility(View.VISIBLE); + }else{ + resultsList.setVisibility(View.VISIBLE); + } + resp = "failed"; + } + }); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/NotificationFragment.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/NotificationFragment.java new file mode 100644 index 0000000..a6bf629 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/NotificationFragment.java @@ -0,0 +1,190 @@ +package com.sdsmdg.bookshareapp.BSA.ui.fragments; + +import android.content.Context; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.sdsmdg.bookshareapp.BSA.Listeners.EndlessScrollListener; +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.Notification.Notification_Model; +import com.sdsmdg.bookshareapp.BSA.api.models.Notification.Notifications; +import com.sdsmdg.bookshareapp.BSA.ui.MainActivity; +import com.sdsmdg.bookshareapp.BSA.ui.adapter.Local.NotificationAdapter; +import com.sdsmdg.bookshareapp.BSA.utils.CommonUtilities; +import com.sdsmdg.bookshareapp.BSA.utils.Helper; + +import java.util.ArrayList; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class NotificationFragment extends Fragment { + + RecyclerView notificationsListView; + LinearLayoutManager nLinearLayoutManager; + NotificationAdapter adapter; + SwipeRefreshLayout refreshLayout; + List notificationsList = new ArrayList<>(); + TextView noNotificationTextView; + SharedPreferences prefs; + + private OnFragmentInteractionListener mListener; + + public NotificationFragment() { + // Required empty public constructor + } + + public static NotificationFragment newInstance(String param1, String param2) { + NotificationFragment fragment = new NotificationFragment(); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View v = inflater.inflate(R.layout.fragment_notification, container, false); + + prefs = getContext().getSharedPreferences("Token", Context.MODE_PRIVATE); + noNotificationTextView = (TextView) v.findViewById(R.id.no_notification_text); + + nLinearLayoutManager = new LinearLayoutManager(getActivity()); + + + notificationsListView = (RecyclerView) v.findViewById(R.id.notifications_list); + notificationsListView.setLayoutManager(nLinearLayoutManager); + + adapter = new NotificationAdapter(getActivity(), notificationsList); + notificationsListView.setAdapter(adapter); + getNotifications("1"); + + final EndlessScrollListener endlessScrollListener = new EndlessScrollListener((LinearLayoutManager) nLinearLayoutManager) { + @Override + public void onLoadMore(int page, int totalItemsCount) { + getNotifications(String.valueOf(page + 1)); + } + }; + + notificationsListView.addOnScrollListener(endlessScrollListener); + + refreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.notif_refresh_layout); + refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + endlessScrollListener.reset(); + getNotifications("1"); + } + }); + return v; + } + + public int getNotifications(final String page) { + + final int[] count = {0}; + + Helper.setOld_total(Helper.getNew_total()); + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(CommonUtilities.local_books_api_url) + .addConverterFactory(GsonConverterFactory.create()) + .build(); + + UsersAPI usersAPI = retrofit.create(UsersAPI.class); + Call call = usersAPI.getNotifs(page, "Token " + prefs.getString("token", null)); + call.enqueue(new Callback() { + + @Override + public void onResponse(Call call, Response response) { + if (response.body() != null) { + + count[0] = Integer.parseInt(response.body().getCount()); + List notifList = response.body().getNotificationsList(); + if (notifList.size() == 0) { + noNotificationTextView.setText("No new notifications"); + noNotificationTextView.setVisibility(View.VISIBLE); + } else { + noNotificationTextView.setVisibility(View.GONE); + } + + if (page.equals("1")) { + notificationsList.clear(); + adapter.notifyDataSetChanged(); + } + + Helper.setNew_total(notifList.size()); + notificationsList.addAll(notifList); + adapter.notifyDataSetChanged(); + refreshLayout.setRefreshing(false); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + noNotificationTextView.setVisibility(View.VISIBLE); + noNotificationTextView.setText("You are offline"); + refreshLayout.setRefreshing(false); + } + }); + return count[0]; + } + + // TODO: Rename method, update argument and hook method into UI event + public void onButtonPressed(Uri uri) { + if (mListener != null) { + mListener.onFragmentInteraction(uri); + } + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof OnFragmentInteractionListener) { + mListener = (OnFragmentInteractionListener) context; + } else { + throw new RuntimeException(context.toString() + + " must implement OnFragmentInteractionListener"); + } + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + /** + * This interface must be implemented by activities that contain this + * fragment to allow an interaction in this fragment to be communicated + * to the activity and potentially other fragments contained in that + * activity. + *

+ * See the Android Training lesson Communicating with Other Fragments for more information. + */ + public interface OnFragmentInteractionListener { + // TODO: Update argument type and name + void onFragmentInteraction(Uri uri); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/SendEmailFragment.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/SendEmailFragment.java new file mode 100644 index 0000000..509d1e1 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/SendEmailFragment.java @@ -0,0 +1,206 @@ +package com.sdsmdg.bookshareapp.BSA.ui.fragments; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.TextInputEditText; +import android.support.design.widget.TextInputLayout; +import android.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.sdsmdg.bookshareapp.BSA.R; +import com.sdsmdg.bookshareapp.BSA.api.NetworkingFactory; +import com.sdsmdg.bookshareapp.BSA.api.UsersAPI; +import com.sdsmdg.bookshareapp.BSA.api.models.VerifyToken.Detail; +import com.sdsmdg.bookshareapp.BSA.ui.CustomProgressDialog; +import com.sdsmdg.bookshareapp.BSA.ui.VerifyOtpActivity; + +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class SendEmailFragment extends Fragment { + + private static final String TITLE = "title"; + private static final String DESCRIPTION = "description"; + private static final String TYPE = "type"; + + private TextInputLayout emailInputLayout; + private TextInputEditText emailInputEditText; + private TextView titleTextView, descriptionTextView; + private CustomProgressDialog customProgressDialog; + private Button submitEmailButton; + private String title; + private String description; + private String type; + private boolean isTypeForgotPassword; + + private OnFragmentInteractionListener mListener; + + public SendEmailFragment() { + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param title Title. + * @param description Description. + * @param type Type + * @return A new instance of fragment SendEmailFragment. + */ + public static SendEmailFragment newInstance(String title, String description, String type) { + SendEmailFragment fragment = new SendEmailFragment(); + Bundle args = new Bundle(); + args.putString(TITLE, title); + args.putString(DESCRIPTION, description); + args.putString(TYPE, type); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + title = getArguments().getString(TITLE); + description = getArguments().getString(DESCRIPTION); + type = getArguments().getString(TYPE); + isTypeForgotPassword = type.equals("forgot_password_email"); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_send_email, container, false); + initViews(view); + setTitle(); + regListeners(); + return view; + } + + private void initViews(View view) { + customProgressDialog = new CustomProgressDialog(getActivity()); + emailInputLayout = (TextInputLayout) view.findViewById(R.id.email_edit_text); + emailInputEditText = (TextInputEditText) view.findViewById(R.id.txt_email_address); + titleTextView = (TextView) view.findViewById(R.id.txt_send_email_heading); + descriptionTextView = (TextView) view.findViewById(R.id.txt_send_email_message); + submitEmailButton = (Button) view.findViewById(R.id.submit_email_button1); + } + + private void regListeners() { + submitEmailButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (emailInputEditText.getText().toString().trim().length() != 0){ + emailInputLayout.setErrorEnabled(false); + sendEmail(emailInputEditText.getText().toString()); + } else{ + emailInputLayout.setErrorEnabled(true); + emailInputLayout.setError("Please enter an email address!!"); + } + } + }); + } + + private void setTitle() { + titleTextView.setText(title); + descriptionTextView.setText(description); + } + + private void sendEmail(final String email) { + customProgressDialog.show(); + UsersAPI usersAPI = NetworkingFactory.getLocalInstance().getUsersAPI(); + Call sendEmailResponse = null; + switch (type) { + case "forgot_password_email": + sendEmailResponse = usersAPI.sendForgotPasswordMail(email); + break; + case "new_activation_email": + sendEmailResponse = usersAPI.sendNewActivationMail(email); + break; + case "new_otp": + sendEmailResponse = usersAPI.sendNewOtp(email); + break; + } + + sendEmailResponse.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + customProgressDialog.dismiss(); + if (response.isSuccessful()){ + emailInputLayout.setEnabled(false); + String detail = response.body().getDetail(); + if (detail.equals("A verification code has been sent")){ + mListener.onFragmentInteraction("success", email); + }else { + Toast.makeText(getActivity(), detail, Toast.LENGTH_SHORT).show(); + mListener.onFragmentInteraction("success", null); + } + } else{ + emailInputLayout.setEnabled(true); + Toast.makeText(getActivity(), "Invalid email address!", Toast.LENGTH_LONG).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + customProgressDialog.dismiss(); + emailInputLayout.setEnabled(true); + Toast.makeText(getActivity(), "Please check your internet connection!", Toast.LENGTH_LONG).show(); + } + }); + } + + @Override + public void onAttach(Activity context) { + super.onAttach(context); + if (context instanceof OnFragmentInteractionListener) { + mListener = (OnFragmentInteractionListener) context; + } else { + throw new RuntimeException(context.toString() + + " must implement OnFragmentInteractionListener"); + } + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof OnFragmentInteractionListener) { + mListener = (OnFragmentInteractionListener) context; + } else { + throw new RuntimeException(context.toString() + + " must implement OnFragmentInteractionListener"); + } + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + /** + * This interface must be implemented by activities that contain this + * fragment to allow an interaction in this fragment to be communicated + * to the activity and potentially other fragments contained in that + * activity. + *

+ * See the Android Training lesson Communicating with Other Fragments for more information. + */ + public interface OnFragmentInteractionListener { + void onFragmentInteraction(String status, String email); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/TutorialFragment.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/TutorialFragment.java new file mode 100644 index 0000000..1fcd687 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/ui/fragments/TutorialFragment.java @@ -0,0 +1,68 @@ +package com.sdsmdg.bookshareapp.BSA.ui.fragments; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.sdsmdg.bookshareapp.BSA.R; + +public class TutorialFragment extends Fragment { + + public static final String TITLE = "title"; + public static final String DESCRIPTION = "description"; + public static final String LOGO_ID = "logoId"; + + private String title; + private String description; + private int logoId; + + public TutorialFragment() { + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param title Title. + * @param description Description. + * @param logoId logoId + * @return A new instance of fragment TutorialFragment. + */ + public static TutorialFragment newInstance(String title, String description, int logoId) { + TutorialFragment fragment = new TutorialFragment(); + Bundle args = new Bundle(); + args.putString(TITLE, title); + args.putString(DESCRIPTION, description); + args.putInt(LOGO_ID, logoId); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + title = getArguments().getString(TITLE); + description = getArguments().getString(DESCRIPTION); + logoId = getArguments().getInt(LOGO_ID); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_tutorial, container, false); + TextView titleTextView = (TextView) view.findViewById(R.id.text_title); + TextView descriptionTextView = (TextView) view.findViewById(R.id.text_description); + ImageView logoImageView = (ImageView) view.findViewById(R.id.image_logo); + titleTextView.setText(title); + descriptionTextView.setText(description); + logoImageView.setImageResource(logoId); + return view; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/CommonUtilities.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/CommonUtilities.java new file mode 100644 index 0000000..d350c8b --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/CommonUtilities.java @@ -0,0 +1,16 @@ +package com.sdsmdg.bookshareapp.BSA.utils; + +public class CommonUtilities { + public static final String goodreads_api_url = "https://www.goodreads.com/"; + public static final String SECRET = "rQzlo9szKNphRLQUjkElZsSYfjyHBnwyHgLfbqHWn0";//#gitignore + public static final String API_KEY = "OIPSMQ3VvFcBzdZiP61oA";//#gitignore + public static final String local_books_api_url = "https://bookshare-prod.us-east-2.elasticbeanstalk.com/"; + public static final String currentUserImageUrl = + "https://bookshare-prod.us-east-2.elasticbeanstalk.com/user/image"; + public static final String MESSAGE_BODY_PREFIX = "The one time verification code for Citadel is "; + + public static String getAnotherUserImageUrl(String pk){ + String a = "https://bookshare-prod.us-east-2.elasticbeanstalk.com/other_user/image?user_id=" + pk; + return a; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/FileUtils.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/FileUtils.java new file mode 100644 index 0000000..4ad7dfd --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/FileUtils.java @@ -0,0 +1,148 @@ +package com.sdsmdg.bookshareapp.BSA.utils; + +import android.annotation.TargetApi; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +@TargetApi(19) +public class FileUtils { + + public static String getPath(final Context context, final Uri uri) { + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } + + // TODO handle non-primary volumes + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{ + split[1] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + + // Return the remote address + if (isGooglePhotosUri(uri)) + return uri.getLastPathSegment(); + + return getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + private static String getDataColumn(Context context, Uri uri, String selection, + String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { + column + }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + final int index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(index); + } + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + private static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is Google Photos. + */ + private static boolean isGooglePhotosUri(Uri uri) { + return "com.google.android.apps.photos.content".equals(uri.getAuthority()); + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/Helper.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/Helper.java new file mode 100644 index 0000000..5f18558 --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/Helper.java @@ -0,0 +1,116 @@ +package com.sdsmdg.bookshareapp.BSA.utils; + +public class Helper { + + private static String accessToken = ""; + private static String accessSecret = ""; + private static String userGRid = null; + + public static String token, id; + + public static String getToken() { + return token; + } + + public static void setToken(String token) { + Helper.token = token; + } + + public static String getId() { + return id; + } + + public static void setId(String id) { + Helper.id = id; + } + + public static String getUserGRid() { + return userGRid; + } + + public static void setUserGRid(String userGRid) { + Helper.userGRid = userGRid; + } + + public static String getAccessToken() { + return accessToken; + } + + public static void setAccessToken(String accessToken) { + Helper.accessToken = accessToken; + } + + public static String getAccessSecret() { + return accessSecret; + } + + public static void setAccessSecret(String accessSecret) { + Helper.accessSecret = accessSecret; + } + + private static String userEmail = ""; + private static String userName = ""; + private static String userId = ""; + private static String bookId = ""; + private static Integer new_total = 0; + private static Integer old_total = 1; + public static boolean imageChanged = false; + + public static Integer getNew_total() { + return new_total; + } + + public static void setNew_total(Integer new_total) { + Helper.new_total = new_total; + } + + public static Integer getOld_total() { + return old_total; + } + + public static void setOld_total(Integer old_total) { + Helper.old_total = old_total; + } + + public static String getBookTitle() { + return bookTitle; + } + + public static void setBookTitle(String bookTitle) { + Helper.bookTitle = bookTitle; + } + + public static String getBookId() { + return bookId; + } + + public static void setBookId(String bookId) { + Helper.bookId = bookId; + } + + private static String bookTitle = ""; + + public static String getUserId() { + return userId; + } + + public static void setUserId(String userId) { + Helper.userId = userId; + } + + public static String getUserName() { + return userName; + } + + public static void setUserName(String userName) { + Helper.userName = userName; + } + + public static String getUserEmail() { + return userEmail; + } + + public static void setUserEmail(String userEmail) { + Helper.userEmail = userEmail; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/PermissionUtils.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/PermissionUtils.java new file mode 100644 index 0000000..9602d8a --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/PermissionUtils.java @@ -0,0 +1,75 @@ +package com.sdsmdg.bookshareapp.BSA.utils; + +import android.Manifest; +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.os.Build; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; + +public class PermissionUtils { + public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123; + private static final int MY_PERMISSIONS_REQUEST_CAMERA = 34; + + public static boolean checkStoragePermission(final Context context) { + int currentAPIVersion = Build.VERSION.SDK_INT; + if (currentAPIVersion >= Build.VERSION_CODES.M) { + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_EXTERNAL_STORAGE)) { + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context); + alertBuilder.setCancelable(true); + alertBuilder.setTitle("Permission necessary"); + alertBuilder.setMessage("External storage permission is necessary"); + alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + public void onClick(DialogInterface dialog, int which) { + ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); + } + }); + AlertDialog alert = alertBuilder.create(); + alert.show(); + } else { + ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); + } + return false; + } else { + return true; + } + } else { + return true; + } + } + + public static boolean checkCameraPermission(final Context context) { + int currentAPIVersion = Build.VERSION.SDK_INT; + if (currentAPIVersion >= Build.VERSION_CODES.M) { + if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) { + if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.CAMERA)) { + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context); + alertBuilder.setCancelable(true); + alertBuilder.setTitle("Permission necessary"); + alertBuilder.setMessage("External storage permission is necessary"); + alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + public void onClick(DialogInterface dialog, int which) { + ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA); + } + }); + AlertDialog alert = alertBuilder.create(); + alert.show(); + } else { + ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA); + } + return false; + } else { + return true; + } + } else { + return true; + } + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/RxSearchObservable.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/RxSearchObservable.java new file mode 100644 index 0000000..f8953ec --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/RxSearchObservable.java @@ -0,0 +1,51 @@ +package com.sdsmdg.bookshareapp.BSA.utils; + +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.TextView; + +import io.reactivex.Observable; +import io.reactivex.subjects.PublishSubject; + +public class RxSearchObservable { + + public static InputMethodManager imm; + + public static Observable fromView(final EditText editText) { + + final PublishSubject subject = PublishSubject.create(); + + editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + subject.onNext(editText.getText().toString()); + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + editText.clearFocus(); + return true; + } + return false; + } + }); + + editText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + subject.onNext(s.toString()); + } + + @Override + public void afterTextChanged(Editable s) { + } + }); + return subject; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/RxSearchViewObservable.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/RxSearchViewObservable.java new file mode 100644 index 0000000..029d12d --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/RxSearchViewObservable.java @@ -0,0 +1,31 @@ +package com.sdsmdg.bookshareapp.BSA.utils; + +import android.support.v7.widget.SearchView; + +import io.reactivex.Observable; +import io.reactivex.subjects.PublishSubject; + +public class RxSearchViewObservable { + + public static Observable fromView(final SearchView searchView) { + + final PublishSubject subject = PublishSubject.create(); + + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String s) { + subject.onNext(s); + searchView.clearFocus(); + return true; + } + + @Override + public boolean onQueryTextChange(String text) { + subject.onNext(text); + return true; + } + }); + + return subject; + } +} diff --git a/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/SPDataLoader.java b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/SPDataLoader.java new file mode 100644 index 0000000..15b43aa --- /dev/null +++ b/app/src/main/java/com/sdsmdg/bookshareapp/BSA/utils/SPDataLoader.java @@ -0,0 +1,29 @@ +package com.sdsmdg.bookshareapp.BSA.utils; + +import android.content.Context; +import android.content.SharedPreferences; + +public class SPDataLoader { + + private SharedPreferences preferences; + + public String getUserName(Context context) { + preferences = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + return preferences.getString("first_name", null) + " " + preferences.getString("last_name", null); + } + + public String getUserEmail(Context context) { + preferences = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + return preferences.getString("email", null); + } + + public String getHostel(Context context) { + preferences = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + return preferences.getString("hostel", null); + } + + public String getRoomNo(Context context) { + preferences = context.getSharedPreferences("Token", Context.MODE_PRIVATE); + return preferences.getString("room_no", null); + } +} diff --git a/app/src/main/res/anim/left_to_right_end.xml b/app/src/main/res/anim/left_to_right_end.xml new file mode 100644 index 0000000..49edc4b --- /dev/null +++ b/app/src/main/res/anim/left_to_right_end.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/left_to_right_start.xml b/app/src/main/res/anim/left_to_right_start.xml new file mode 100644 index 0000000..7b475c2 --- /dev/null +++ b/app/src/main/res/anim/left_to_right_start.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/right_to_left_end.xml b/app/src/main/res/anim/right_to_left_end.xml new file mode 100644 index 0000000..67fa6cc --- /dev/null +++ b/app/src/main/res/anim/right_to_left_end.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/right_to_left_start.xml b/app/src/main/res/anim/right_to_left_start.xml new file mode 100644 index 0000000..d2bb06a --- /dev/null +++ b/app/src/main/res/anim/right_to_left_start.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/add_books_group.png b/app/src/main/res/drawable-hdpi/add_books_group.png new file mode 100644 index 0000000..5fc0437 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/add_books_group.png differ diff --git a/app/src/main/res/drawable-hdpi/campus_books_group.png b/app/src/main/res/drawable-hdpi/campus_books_group.png new file mode 100644 index 0000000..c8cdc7a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/campus_books_group.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_account_circle_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_account_circle_black_24dp.png new file mode 100644 index 0000000..ba5a509 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_account_circle_black_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..694179b Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_book_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_book_white_24dp.png new file mode 100644 index 0000000..0fd780e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_book_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_exit_to_app_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_exit_to_app_white_24dp.png new file mode 100644 index 0000000..52565d0 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_exit_to_app_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_notifications_none_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_notifications_none_white_24dp.png new file mode 100644 index 0000000..b998c8c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_notifications_none_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/user_search_group.png b/app/src/main/res/drawable-hdpi/user_search_group.png new file mode 100644 index 0000000..c02bc95 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/user_search_group.png differ diff --git a/app/src/main/res/drawable-mdpi/add_books_group.png b/app/src/main/res/drawable-mdpi/add_books_group.png new file mode 100644 index 0000000..5fc0437 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/add_books_group.png differ diff --git a/app/src/main/res/drawable-mdpi/campus_books_group.png b/app/src/main/res/drawable-mdpi/campus_books_group.png new file mode 100644 index 0000000..c8cdc7a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/campus_books_group.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_account_circle_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_account_circle_black_24dp.png new file mode 100644 index 0000000..0c1202d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_account_circle_black_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..3856041 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_book_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_book_white_24dp.png new file mode 100644 index 0000000..8b02f9a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_book_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_exit_to_app_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_exit_to_app_white_24dp.png new file mode 100644 index 0000000..461be00 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_exit_to_app_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_notifications_none_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_notifications_none_white_24dp.png new file mode 100644 index 0000000..45f4704 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_notifications_none_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/user_search_group.png b/app/src/main/res/drawable-mdpi/user_search_group.png new file mode 100644 index 0000000..c02bc95 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/user_search_group.png differ diff --git a/app/src/main/res/drawable-xhdpi/add_books_group.png b/app/src/main/res/drawable-xhdpi/add_books_group.png new file mode 100644 index 0000000..5fc0437 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/add_books_group.png differ diff --git a/app/src/main/res/drawable-xhdpi/campus_books_group.png b/app/src/main/res/drawable-xhdpi/campus_books_group.png new file mode 100644 index 0000000..c8cdc7a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/campus_books_group.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_account_circle_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_account_circle_black_24dp.png new file mode 100644 index 0000000..f26b201 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_account_circle_black_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..67bb598 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_book_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_book_white_24dp.png new file mode 100644 index 0000000..5a5ee30 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_book_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_exit_to_app_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_exit_to_app_white_24dp.png new file mode 100644 index 0000000..07847bd Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_exit_to_app_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_notifications_none_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_notifications_none_white_24dp.png new file mode 100644 index 0000000..19eba20 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_notifications_none_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/user_search_group.png b/app/src/main/res/drawable-xhdpi/user_search_group.png new file mode 100644 index 0000000..c02bc95 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/user_search_group.png differ diff --git a/app/src/main/res/drawable-xxhdpi/add_books_group.png b/app/src/main/res/drawable-xxhdpi/add_books_group.png new file mode 100644 index 0000000..5fc0437 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/add_books_group.png differ diff --git a/app/src/main/res/drawable-xxhdpi/campus_books_group.png b/app/src/main/res/drawable-xxhdpi/campus_books_group.png new file mode 100644 index 0000000..c8cdc7a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/campus_books_group.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_account_circle_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_account_circle_black_24dp.png new file mode 100644 index 0000000..3cc0a63 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_account_circle_black_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..0fdced8 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_book_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_book_white_24dp.png new file mode 100644 index 0000000..d181a32 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_book_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_exit_to_app_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_exit_to_app_white_24dp.png new file mode 100644 index 0000000..c04fe6e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_exit_to_app_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_notifications_none_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_notifications_none_white_24dp.png new file mode 100644 index 0000000..a1b5b7e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_notifications_none_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/user_search_group.png b/app/src/main/res/drawable-xxhdpi/user_search_group.png new file mode 100644 index 0000000..c02bc95 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/user_search_group.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/add_books_group.png b/app/src/main/res/drawable-xxxhdpi/add_books_group.png new file mode 100644 index 0000000..5fc0437 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/add_books_group.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/background.png b/app/src/main/res/drawable-xxxhdpi/background.png new file mode 100644 index 0000000..b0683b5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/background.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/campus_books_group.png b/app/src/main/res/drawable-xxxhdpi/campus_books_group.png new file mode 100644 index 0000000..c8cdc7a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/campus_books_group.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_account_circle_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_account_circle_black_24dp.png new file mode 100644 index 0000000..c6b56c3 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_account_circle_black_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..d64c22e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_book_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_book_white_24dp.png new file mode 100644 index 0000000..938eff4 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_book_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_cross.png b/app/src/main/res/drawable-xxxhdpi/ic_cross.png new file mode 100644 index 0000000..6f5bcfb Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_cross.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_white_24dp.png new file mode 100644 index 0000000..27a9d7b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..3d3d0c2 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_logout.png b/app/src/main/res/drawable-xxxhdpi/ic_logout.png new file mode 100644 index 0000000..300c4bf Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_logout.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_mail.png b/app/src/main/res/drawable-xxxhdpi/ic_mail.png new file mode 100644 index 0000000..dfd7887 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_mail.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_navopen.png b/app/src/main/res/drawable-xxxhdpi/ic_navopen.png new file mode 100644 index 0000000..4422302 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_navopen.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_notif_small.png b/app/src/main/res/drawable-xxxhdpi/ic_notif_small.png new file mode 100644 index 0000000..353073a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_notif_small.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_notifications_none_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_notifications_none_white_24dp.png new file mode 100644 index 0000000..d4627a9 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_notifications_none_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_person_filled.png b/app/src/main/res/drawable-xxxhdpi/ic_person_filled.png new file mode 100644 index 0000000..b1f3cc6 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_person_filled.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_profile.png b/app/src/main/res/drawable-xxxhdpi/ic_profile.png new file mode 100644 index 0000000..25632fb Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_profile.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_profile_pic.png b/app/src/main/res/drawable-xxxhdpi/ic_profile_pic.png new file mode 100644 index 0000000..859330a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_profile_pic.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_search.png b/app/src/main/res/drawable-xxxhdpi/ic_search.png new file mode 100644 index 0000000..4e54f27 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_search.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_share.png b/app/src/main/res/drawable-xxxhdpi/ic_share.png new file mode 100644 index 0000000..217c078 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_share.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_star_filled.png b/app/src/main/res/drawable-xxxhdpi/ic_star_filled.png new file mode 100644 index 0000000..c175181 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_star_filled.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_to_read.png b/app/src/main/res/drawable-xxxhdpi/ic_to_read.png new file mode 100644 index 0000000..46b1b07 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_to_read.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_visibility_off_96px.png b/app/src/main/res/drawable-xxxhdpi/ic_visibility_off_96px.png new file mode 100644 index 0000000..bf2c41a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_visibility_off_96px.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_visible_off.png b/app/src/main/res/drawable-xxxhdpi/ic_visible_off.png new file mode 100644 index 0000000..42f83a5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_visible_off.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_visible_on.png b/app/src/main/res/drawable-xxxhdpi/ic_visible_on.png new file mode 100644 index 0000000..c6f790a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_visible_on.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/logo1.png b/app/src/main/res/drawable-xxxhdpi/logo1.png new file mode 100644 index 0000000..31ad382 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/logo1.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/logo2.png b/app/src/main/res/drawable-xxxhdpi/logo2.png new file mode 100644 index 0000000..6e435b9 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/logo2.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/logo3.png b/app/src/main/res/drawable-xxxhdpi/logo3.png new file mode 100644 index 0000000..cc41fe0 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/logo3.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/logo4.png b/app/src/main/res/drawable-xxxhdpi/logo4.png new file mode 100644 index 0000000..58787b9 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/logo4.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/navdrawer2.jpg b/app/src/main/res/drawable-xxxhdpi/navdrawer2.jpg new file mode 100644 index 0000000..5396752 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/navdrawer2.jpg differ diff --git a/app/src/main/res/drawable-xxxhdpi/plus3.png b/app/src/main/res/drawable-xxxhdpi/plus3.png new file mode 100644 index 0000000..db8338c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/plus3.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/splash3.png b/app/src/main/res/drawable-xxxhdpi/splash3.png new file mode 100644 index 0000000..1c97df1 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/splash3.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/star.png b/app/src/main/res/drawable-xxxhdpi/star.png new file mode 100644 index 0000000..c07858a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/star.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/user_search_group.png b/app/src/main/res/drawable-xxxhdpi/user_search_group.png new file mode 100644 index 0000000..c02bc95 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/user_search_group.png differ diff --git a/app/src/main/res/drawable/add_books_group.png b/app/src/main/res/drawable/add_books_group.png new file mode 100644 index 0000000..5fc0437 Binary files /dev/null and b/app/src/main/res/drawable/add_books_group.png differ diff --git a/app/src/main/res/drawable/b0.png b/app/src/main/res/drawable/b0.png new file mode 100644 index 0000000..c37fa50 Binary files /dev/null and b/app/src/main/res/drawable/b0.png differ diff --git a/app/src/main/res/drawable/b1.png b/app/src/main/res/drawable/b1.png new file mode 100644 index 0000000..96be259 Binary files /dev/null and b/app/src/main/res/drawable/b1.png differ diff --git a/app/src/main/res/drawable/b2.png b/app/src/main/res/drawable/b2.png new file mode 100644 index 0000000..e7a6fc8 Binary files /dev/null and b/app/src/main/res/drawable/b2.png differ diff --git a/app/src/main/res/drawable/b3.png b/app/src/main/res/drawable/b3.png new file mode 100644 index 0000000..24b616e Binary files /dev/null and b/app/src/main/res/drawable/b3.png differ diff --git a/app/src/main/res/drawable/b4.png b/app/src/main/res/drawable/b4.png new file mode 100644 index 0000000..0bfe759 Binary files /dev/null and b/app/src/main/res/drawable/b4.png differ diff --git a/app/src/main/res/drawable/b5.png b/app/src/main/res/drawable/b5.png new file mode 100644 index 0000000..f6c1392 Binary files /dev/null and b/app/src/main/res/drawable/b5.png differ diff --git a/app/src/main/res/drawable/border_progress.xml b/app/src/main/res/drawable/border_progress.xml new file mode 100644 index 0000000..b57d685 --- /dev/null +++ b/app/src/main/res/drawable/border_progress.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/border_progress2.xml b/app/src/main/res/drawable/border_progress2.xml new file mode 100644 index 0000000..bd37927 --- /dev/null +++ b/app/src/main/res/drawable/border_progress2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/button_shape.xml b/app/src/main/res/drawable/button_shape.xml new file mode 100644 index 0000000..d890871 --- /dev/null +++ b/app/src/main/res/drawable/button_shape.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/button_shape_other.xml b/app/src/main/res/drawable/button_shape_other.xml new file mode 100644 index 0000000..85e9c6c --- /dev/null +++ b/app/src/main/res/drawable/button_shape_other.xml @@ -0,0 +1,19 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/call.png b/app/src/main/res/drawable/call.png new file mode 100644 index 0000000..7357b7e Binary files /dev/null and b/app/src/main/res/drawable/call.png differ diff --git a/app/src/main/res/drawable/campus_books_group.png b/app/src/main/res/drawable/campus_books_group.png new file mode 100644 index 0000000..c8cdc7a Binary files /dev/null and b/app/src/main/res/drawable/campus_books_group.png differ diff --git a/app/src/main/res/drawable/change_image.png b/app/src/main/res/drawable/change_image.png new file mode 100644 index 0000000..b081947 Binary files /dev/null and b/app/src/main/res/drawable/change_image.png differ diff --git a/app/src/main/res/drawable/circle.xml b/app/src/main/res/drawable/circle.xml new file mode 100644 index 0000000..0dba04d --- /dev/null +++ b/app/src/main/res/drawable/circle.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/current_page_dot.xml b/app/src/main/res/drawable/current_page_dot.xml new file mode 100644 index 0000000..e026f93 --- /dev/null +++ b/app/src/main/res/drawable/current_page_dot.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/default_book_image.png b/app/src/main/res/drawable/default_book_image.png new file mode 100644 index 0000000..26038e2 Binary files /dev/null and b/app/src/main/res/drawable/default_book_image.png differ diff --git a/app/src/main/res/drawable/edit_books_details.png b/app/src/main/res/drawable/edit_books_details.png new file mode 100644 index 0000000..01809d6 Binary files /dev/null and b/app/src/main/res/drawable/edit_books_details.png differ diff --git a/app/src/main/res/drawable/envelope.png b/app/src/main/res/drawable/envelope.png new file mode 100644 index 0000000..b8f09b5 Binary files /dev/null and b/app/src/main/res/drawable/envelope.png differ diff --git a/app/src/main/res/drawable/error.png b/app/src/main/res/drawable/error.png new file mode 100644 index 0000000..e26c5ea Binary files /dev/null and b/app/src/main/res/drawable/error.png differ diff --git a/app/src/main/res/drawable/ic_barcode.xml b/app/src/main/res/drawable/ic_barcode.xml new file mode 100644 index 0000000..bf3bc0a --- /dev/null +++ b/app/src/main/res/drawable/ic_barcode.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_book_white_48dp.png b/app/src/main/res/drawable/ic_book_white_48dp.png new file mode 100644 index 0000000..d181a32 Binary files /dev/null and b/app/src/main/res/drawable/ic_book_white_48dp.png differ diff --git a/app/src/main/res/drawable/ic_call_white_48dp.png b/app/src/main/res/drawable/ic_call_white_48dp.png new file mode 100644 index 0000000..a8e295a Binary files /dev/null and b/app/src/main/res/drawable/ic_call_white_48dp.png differ diff --git a/app/src/main/res/drawable/ic_check_black_24dp.xml b/app/src/main/res/drawable/ic_check_black_24dp.xml new file mode 100644 index 0000000..fb13677 --- /dev/null +++ b/app/src/main/res/drawable/ic_check_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_clear_24dp.xml b/app/src/main/res/drawable/ic_clear_24dp.xml new file mode 100644 index 0000000..ede4b71 --- /dev/null +++ b/app/src/main/res/drawable/ic_clear_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_cross_green.png b/app/src/main/res/drawable/ic_cross_green.png new file mode 100644 index 0000000..d839a74 Binary files /dev/null and b/app/src/main/res/drawable/ic_cross_green.png differ diff --git a/app/src/main/res/drawable/ic_edit_white_48dp.png b/app/src/main/res/drawable/ic_edit_white_48dp.png new file mode 100644 index 0000000..377b2e8 Binary files /dev/null and b/app/src/main/res/drawable/ic_edit_white_48dp.png differ diff --git a/app/src/main/res/drawable/ic_email_white_48dp.png b/app/src/main/res/drawable/ic_email_white_48dp.png new file mode 100644 index 0000000..309263b Binary files /dev/null and b/app/src/main/res/drawable/ic_email_white_48dp.png differ diff --git a/app/src/main/res/drawable/ic_insert_photo_white_48dp.png b/app/src/main/res/drawable/ic_insert_photo_white_48dp.png new file mode 100644 index 0000000..3fe5c5c Binary files /dev/null and b/app/src/main/res/drawable/ic_insert_photo_white_48dp.png differ diff --git a/app/src/main/res/drawable/ic_menu_camera.xml b/app/src/main/res/drawable/ic_menu_camera.xml new file mode 100644 index 0000000..0d9ea10 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_camera.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_menu_gallery.xml b/app/src/main/res/drawable/ic_menu_gallery.xml new file mode 100644 index 0000000..f6872c4 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_gallery.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu_manage.xml b/app/src/main/res/drawable/ic_menu_manage.xml new file mode 100644 index 0000000..c1be60b --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_manage.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_menu_send.xml b/app/src/main/res/drawable/ic_menu_send.xml new file mode 100644 index 0000000..00c668c --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_send.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu_send2.xml b/app/src/main/res/drawable/ic_menu_send2.xml new file mode 100644 index 0000000..6277755 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_send2.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu_share.xml b/app/src/main/res/drawable/ic_menu_share.xml new file mode 100644 index 0000000..a28fb9e --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_share.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu_slideshow.xml b/app/src/main/res/drawable/ic_menu_slideshow.xml new file mode 100644 index 0000000..209aa64 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_slideshow.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/normal_dot.xml b/app/src/main/res/drawable/normal_dot.xml new file mode 100644 index 0000000..fca2733 --- /dev/null +++ b/app/src/main/res/drawable/normal_dot.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/notification_group.xml b/app/src/main/res/drawable/notification_group.xml new file mode 100644 index 0000000..4bd3db2 --- /dev/null +++ b/app/src/main/res/drawable/notification_group.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/pen.png b/app/src/main/res/drawable/pen.png new file mode 100644 index 0000000..54025a7 Binary files /dev/null and b/app/src/main/res/drawable/pen.png differ diff --git a/app/src/main/res/drawable/phone.png b/app/src/main/res/drawable/phone.png new file mode 100644 index 0000000..a3cbcb3 Binary files /dev/null and b/app/src/main/res/drawable/phone.png differ diff --git a/app/src/main/res/drawable/progress_indeterminate_horizontal.xml b/app/src/main/res/drawable/progress_indeterminate_horizontal.xml new file mode 100644 index 0000000..210acce --- /dev/null +++ b/app/src/main/res/drawable/progress_indeterminate_horizontal.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/search_icon.png b/app/src/main/res/drawable/search_icon.png new file mode 100644 index 0000000..bbfbc96 Binary files /dev/null and b/app/src/main/res/drawable/search_icon.png differ diff --git a/app/src/main/res/drawable/up2.png b/app/src/main/res/drawable/up2.png new file mode 100644 index 0000000..2d4f024 Binary files /dev/null and b/app/src/main/res/drawable/up2.png differ diff --git a/app/src/main/res/drawable/user_default_image.png b/app/src/main/res/drawable/user_default_image.png new file mode 100644 index 0000000..9d1789a Binary files /dev/null and b/app/src/main/res/drawable/user_default_image.png differ diff --git a/app/src/main/res/drawable/user_search_group.png b/app/src/main/res/drawable/user_search_group.png new file mode 100644 index 0000000..c02bc95 Binary files /dev/null and b/app/src/main/res/drawable/user_search_group.png differ diff --git a/app/src/main/res/drawable/window_dim.xml b/app/src/main/res/drawable/window_dim.xml new file mode 100644 index 0000000..dbc433c --- /dev/null +++ b/app/src/main/res/drawable/window_dim.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/layout/activity_books_details.xml b/app/src/main/res/layout/activity_books_details.xml new file mode 100644 index 0000000..e043363 --- /dev/null +++ b/app/src/main/res/layout/activity_books_details.xml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +