| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,16 @@ |
| 1 |
+*.iml |
|
| 2 |
+.gradle |
|
| 3 |
+/local.properties |
|
| 4 |
+/.idea/caches |
|
| 5 |
+/.idea/libraries |
|
| 6 |
+/.idea/modules.xml |
|
| 7 |
+/.idea/workspace.xml |
|
| 8 |
+/.idea/navEditor.xml |
|
| 9 |
+/.idea/assetWizardSettings.xml |
|
| 10 |
+/.idea/deploymentTargetDropDown.xml |
|
| 11 |
+.DS_Store |
|
| 12 |
+/build |
|
| 13 |
+/captures |
|
| 14 |
+.externalNativeBuild |
|
| 15 |
+.cxx |
|
| 16 |
+local.properties |
| 2 | 19 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,13 @@ |
| 1 |
+## 👋 Welcome Dev!, Thanks for making this `Audio Notes App` great ♥️. |
|
| 2 |
+ |
|
| 3 |
+### 💬 What you can do |
|
| 4 |
+ |
|
| 5 |
+You can contribute us by `filing issues`, `bugs` and `PRs`. |
|
| 6 |
+ |
|
| 7 |
+### ✅ Contributing guidelines: |
|
| 8 |
+ |
|
| 9 |
+- Open issue regarding proposed change. |
|
| 10 |
+- Repo owner will contact you there. |
|
| 11 |
+- If your proposed change is approved, Fork this repo and do changes. |
|
| 12 |
+- Open PR against latest `dev` branch. Add nice description in PR. |
|
| 13 |
+- You're done! |
| 0 | 14 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,201 @@ |
| 1 |
+ Apache License |
|
| 2 |
+ Version 2.0, January 2004 |
|
| 3 |
+ http://www.apache.org/licenses/ |
|
| 4 |
+ |
|
| 5 |
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
|
| 6 |
+ |
|
| 7 |
+ 1. Definitions. |
|
| 8 |
+ |
|
| 9 |
+ "License" shall mean the terms and conditions for use, reproduction, |
|
| 10 |
+ and distribution as defined by Sections 1 through 9 of this document. |
|
| 11 |
+ |
|
| 12 |
+ "Licensor" shall mean the copyright owner or entity authorized by |
|
| 13 |
+ the copyright owner that is granting the License. |
|
| 14 |
+ |
|
| 15 |
+ "Legal Entity" shall mean the union of the acting entity and all |
|
| 16 |
+ other entities that control, are controlled by, or are under common |
|
| 17 |
+ control with that entity. For the purposes of this definition, |
|
| 18 |
+ "control" means (i) the power, direct or indirect, to cause the |
|
| 19 |
+ direction or management of such entity, whether by contract or |
|
| 20 |
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the |
|
| 21 |
+ outstanding shares, or (iii) beneficial ownership of such entity. |
|
| 22 |
+ |
|
| 23 |
+ "You" (or "Your") shall mean an individual or Legal Entity |
|
| 24 |
+ exercising permissions granted by this License. |
|
| 25 |
+ |
|
| 26 |
+ "Source" form shall mean the preferred form for making modifications, |
|
| 27 |
+ including but not limited to software source code, documentation |
|
| 28 |
+ source, and configuration files. |
|
| 29 |
+ |
|
| 30 |
+ "Object" form shall mean any form resulting from mechanical |
|
| 31 |
+ transformation or translation of a Source form, including but |
|
| 32 |
+ not limited to compiled object code, generated documentation, |
|
| 33 |
+ and conversions to other media types. |
|
| 34 |
+ |
|
| 35 |
+ "Work" shall mean the work of authorship, whether in Source or |
|
| 36 |
+ Object form, made available under the License, as indicated by a |
|
| 37 |
+ copyright notice that is included in or attached to the work |
|
| 38 |
+ (an example is provided in the Appendix below). |
|
| 39 |
+ |
|
| 40 |
+ "Derivative Works" shall mean any work, whether in Source or Object |
|
| 41 |
+ form, that is based on (or derived from) the Work and for which the |
|
| 42 |
+ editorial revisions, annotations, elaborations, or other modifications |
|
| 43 |
+ represent, as a whole, an original work of authorship. For the purposes |
|
| 44 |
+ of this License, Derivative Works shall not include works that remain |
|
| 45 |
+ separable from, or merely link (or bind by name) to the interfaces of, |
|
| 46 |
+ the Work and Derivative Works thereof. |
|
| 47 |
+ |
|
| 48 |
+ "Contribution" shall mean any work of authorship, including |
|
| 49 |
+ the original version of the Work and any modifications or additions |
|
| 50 |
+ to that Work or Derivative Works thereof, that is intentionally |
|
| 51 |
+ submitted to Licensor for inclusion in the Work by the copyright owner |
|
| 52 |
+ or by an individual or Legal Entity authorized to submit on behalf of |
|
| 53 |
+ the copyright owner. For the purposes of this definition, "submitted" |
|
| 54 |
+ means any form of electronic, verbal, or written communication sent |
|
| 55 |
+ to the Licensor or its representatives, including but not limited to |
|
| 56 |
+ communication on electronic mailing lists, source code control systems, |
|
| 57 |
+ and issue tracking systems that are managed by, or on behalf of, the |
|
| 58 |
+ Licensor for the purpose of discussing and improving the Work, but |
|
| 59 |
+ excluding communication that is conspicuously marked or otherwise |
|
| 60 |
+ designated in writing by the copyright owner as "Not a Contribution." |
|
| 61 |
+ |
|
| 62 |
+ "Contributor" shall mean Licensor and any individual or Legal Entity |
|
| 63 |
+ on behalf of whom a Contribution has been received by Licensor and |
|
| 64 |
+ subsequently incorporated within the Work. |
|
| 65 |
+ |
|
| 66 |
+ 2. Grant of Copyright License. Subject to the terms and conditions of |
|
| 67 |
+ this License, each Contributor hereby grants to You a perpetual, |
|
| 68 |
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|
| 69 |
+ copyright license to reproduce, prepare Derivative Works of, |
|
| 70 |
+ publicly display, publicly perform, sublicense, and distribute the |
|
| 71 |
+ Work and such Derivative Works in Source or Object form. |
|
| 72 |
+ |
|
| 73 |
+ 3. Grant of Patent License. Subject to the terms and conditions of |
|
| 74 |
+ this License, each Contributor hereby grants to You a perpetual, |
|
| 75 |
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|
| 76 |
+ (except as stated in this section) patent license to make, have made, |
|
| 77 |
+ use, offer to sell, sell, import, and otherwise transfer the Work, |
|
| 78 |
+ where such license applies only to those patent claims licensable |
|
| 79 |
+ by such Contributor that are necessarily infringed by their |
|
| 80 |
+ Contribution(s) alone or by combination of their Contribution(s) |
|
| 81 |
+ with the Work to which such Contribution(s) was submitted. If You |
|
| 82 |
+ institute patent litigation against any entity (including a |
|
| 83 |
+ cross-claim or counterclaim in a lawsuit) alleging that the Work |
|
| 84 |
+ or a Contribution incorporated within the Work constitutes direct |
|
| 85 |
+ or contributory patent infringement, then any patent licenses |
|
| 86 |
+ granted to You under this License for that Work shall terminate |
|
| 87 |
+ as of the date such litigation is filed. |
|
| 88 |
+ |
|
| 89 |
+ 4. Redistribution. You may reproduce and distribute copies of the |
|
| 90 |
+ Work or Derivative Works thereof in any medium, with or without |
|
| 91 |
+ modifications, and in Source or Object form, provided that You |
|
| 92 |
+ meet the following conditions: |
|
| 93 |
+ |
|
| 94 |
+ (a) You must give any other recipients of the Work or |
|
| 95 |
+ Derivative Works a copy of this License; and |
|
| 96 |
+ |
|
| 97 |
+ (b) You must cause any modified files to carry prominent notices |
|
| 98 |
+ stating that You changed the files; and |
|
| 99 |
+ |
|
| 100 |
+ (c) You must retain, in the Source form of any Derivative Works |
|
| 101 |
+ that You distribute, all copyright, patent, trademark, and |
|
| 102 |
+ attribution notices from the Source form of the Work, |
|
| 103 |
+ excluding those notices that do not pertain to any part of |
|
| 104 |
+ the Derivative Works; and |
|
| 105 |
+ |
|
| 106 |
+ (d) If the Work includes a "NOTICE" text file as part of its |
|
| 107 |
+ distribution, then any Derivative Works that You distribute must |
|
| 108 |
+ include a readable copy of the attribution notices contained |
|
| 109 |
+ within such NOTICE file, excluding those notices that do not |
|
| 110 |
+ pertain to any part of the Derivative Works, in at least one |
|
| 111 |
+ of the following places: within a NOTICE text file distributed |
|
| 112 |
+ as part of the Derivative Works; within the Source form or |
|
| 113 |
+ documentation, if provided along with the Derivative Works; or, |
|
| 114 |
+ within a display generated by the Derivative Works, if and |
|
| 115 |
+ wherever such third-party notices normally appear. The contents |
|
| 116 |
+ of the NOTICE file are for informational purposes only and |
|
| 117 |
+ do not modify the License. You may add Your own attribution |
|
| 118 |
+ notices within Derivative Works that You distribute, alongside |
|
| 119 |
+ or as an addendum to the NOTICE text from the Work, provided |
|
| 120 |
+ that such additional attribution notices cannot be construed |
|
| 121 |
+ as modifying the License. |
|
| 122 |
+ |
|
| 123 |
+ You may add Your own copyright statement to Your modifications and |
|
| 124 |
+ may provide additional or different license terms and conditions |
|
| 125 |
+ for use, reproduction, or distribution of Your modifications, or |
|
| 126 |
+ for any such Derivative Works as a whole, provided Your use, |
|
| 127 |
+ reproduction, and distribution of the Work otherwise complies with |
|
| 128 |
+ the conditions stated in this License. |
|
| 129 |
+ |
|
| 130 |
+ 5. Submission of Contributions. Unless You explicitly state otherwise, |
|
| 131 |
+ any Contribution intentionally submitted for inclusion in the Work |
|
| 132 |
+ by You to the Licensor shall be under the terms and conditions of |
|
| 133 |
+ this License, without any additional terms or conditions. |
|
| 134 |
+ Notwithstanding the above, nothing herein shall supersede or modify |
|
| 135 |
+ the terms of any separate license agreement you may have executed |
|
| 136 |
+ with Licensor regarding such Contributions. |
|
| 137 |
+ |
|
| 138 |
+ 6. Trademarks. This License does not grant permission to use the trade |
|
| 139 |
+ names, trademarks, service marks, or product names of the Licensor, |
|
| 140 |
+ except as required for reasonable and customary use in describing the |
|
| 141 |
+ origin of the Work and reproducing the content of the NOTICE file. |
|
| 142 |
+ |
|
| 143 |
+ 7. Disclaimer of Warranty. Unless required by applicable law or |
|
| 144 |
+ agreed to in writing, Licensor provides the Work (and each |
|
| 145 |
+ Contributor provides its Contributions) on an "AS IS" BASIS, |
|
| 146 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
|
| 147 |
+ implied, including, without limitation, any warranties or conditions |
|
| 148 |
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
|
| 149 |
+ PARTICULAR PURPOSE. You are solely responsible for determining the |
|
| 150 |
+ appropriateness of using or redistributing the Work and assume any |
|
| 151 |
+ risks associated with Your exercise of permissions under this License. |
|
| 152 |
+ |
|
| 153 |
+ 8. Limitation of Liability. In no event and under no legal theory, |
|
| 154 |
+ whether in tort (including negligence), contract, or otherwise, |
|
| 155 |
+ unless required by applicable law (such as deliberate and grossly |
|
| 156 |
+ negligent acts) or agreed to in writing, shall any Contributor be |
|
| 157 |
+ liable to You for damages, including any direct, indirect, special, |
|
| 158 |
+ incidental, or consequential damages of any character arising as a |
|
| 159 |
+ result of this License or out of the use or inability to use the |
|
| 160 |
+ Work (including but not limited to damages for loss of goodwill, |
|
| 161 |
+ work stoppage, computer failure or malfunction, or any and all |
|
| 162 |
+ other commercial damages or losses), even if such Contributor |
|
| 163 |
+ has been advised of the possibility of such damages. |
|
| 164 |
+ |
|
| 165 |
+ 9. Accepting Warranty or Additional Liability. While redistributing |
|
| 166 |
+ the Work or Derivative Works thereof, You may choose to offer, |
|
| 167 |
+ and charge a fee for, acceptance of support, warranty, indemnity, |
|
| 168 |
+ or other liability obligations and/or rights consistent with this |
|
| 169 |
+ License. However, in accepting such obligations, You may act only |
|
| 170 |
+ on Your own behalf and on Your sole responsibility, not on behalf |
|
| 171 |
+ of any other Contributor, and only if You agree to indemnify, |
|
| 172 |
+ defend, and hold each Contributor harmless for any liability |
|
| 173 |
+ incurred by, or claims asserted against, such Contributor by reason |
|
| 174 |
+ of your accepting any such warranty or additional liability. |
|
| 175 |
+ |
|
| 176 |
+ END OF TERMS AND CONDITIONS |
|
| 177 |
+ |
|
| 178 |
+ APPENDIX: How to apply the Apache License to your work. |
|
| 179 |
+ |
|
| 180 |
+ To apply the Apache License to your work, attach the following |
|
| 181 |
+ boilerplate notice, with the fields enclosed by brackets "[]" |
|
| 182 |
+ replaced with your own identifying information. (Don't include |
|
| 183 |
+ the brackets!) The text should be enclosed in the appropriate |
|
| 184 |
+ comment syntax for the file format. We also recommend that a |
|
| 185 |
+ file or class name and description of purpose be included on the |
|
| 186 |
+ same "printed page" as the copyright notice for easier |
|
| 187 |
+ identification within third-party archives. |
|
| 188 |
+ |
|
| 189 |
+ Copyright 2021 Samson Achiaga |
|
| 190 |
+ |
|
| 191 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 192 |
+ you may not use this file except in compliance with the License. |
|
| 193 |
+ You may obtain a copy of the License at |
|
| 194 |
+ |
|
| 195 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 196 |
+ |
|
| 197 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 198 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 199 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 200 |
+ See the License for the specific language governing permissions and |
|
| 201 |
+ limitations under the License. |
| 0 | 202 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,152 @@ |
| 1 |
+# AudioNotes 📙 |
|
| 2 |
+A simple open source audio note-taking 📝 Android application built to describe the use of Modern Android development tools. 🏗. *Made with love ❤️ by [Sammie_kt](https://github.com/certified84)* |
|
| 3 |
+ |
|
| 4 |
+<br /> |
|
| 5 |
+ |
|
| 6 |
+***Find the latest stable release here👇*** |
|
| 7 |
+ |
|
| 8 |
+[](https://github.com/certified84/AudioNote/releases/latest) |
|
| 9 |
+ |
|
| 10 |
+[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" |
|
| 11 |
+ alt="Get it on F-Droid" |
|
| 12 |
+ height="80">](https://f-droid.org/packages/com.certified.audionote/) |
|
| 13 |
+ |
|
| 14 |
+<br /> |
|
| 15 |
+ |
|
| 16 |
+***Find the design on figma here👇*** |
|
| 17 |
+ |
|
| 18 |
+[](https://www.figma.com/file/BxFzSMNrfXy8yrQlr8XWAS/Audio-Notes-Project?node-id=3%3A594) |
|
| 19 |
+ |
|
| 20 |
+<br /> |
|
| 21 |
+ |
|
| 22 |
+## Day Mode 🌞 |
|
| 23 |
+Splash | Onboarding | Home(empty) | Home(content) | |
|
| 24 |
+--- | --- | --- | --- | |
|
| 25 |
+ |  |  |  | |
|
| 26 |
+ |
|
| 27 |
+New note | Edit note | Settings | About | |
|
| 28 |
+--- | --- | --- | --- | |
|
| 29 |
+ |  |  |  |
|
| 30 |
+ |
|
| 31 |
+<br /> |
|
| 32 |
+ |
|
| 33 |
+## We Support Dark Mode Too 🌚 |
|
| 34 |
+Splash | Onboarding | Home(empty) | Home(content) | |
|
| 35 |
+--- | --- | --- | --- | |
|
| 36 |
+ |  |  |  | |
|
| 37 |
+ |
|
| 38 |
+New note | Edit note | Settings | About | |
|
| 39 |
+--- | --- | --- | --- | |
|
| 40 |
+ |  |  |  |
|
| 41 |
+ |
|
| 42 |
+<br /> |
|
| 43 |
+ |
|
| 44 |
+ |
|
| 45 |
+## Built With 🛠 |
|
| 46 |
+- [Kotlin](https://kotlinlang.org/) - First class and official programming language for Android development. |
|
| 47 |
+- [Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html) - For asynchronous and more.. |
|
| 48 |
+- [Android Architecture Components](https://developer.android.com/topic/libraries/architecture) - Collection of libraries that help you design robust, testable, and maintainable apps. |
|
| 49 |
+ - [ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel) - Stores UI-related data that isn't destroyed on UI changes. |
|
| 50 |
+ - [Room](https://developer.android.com/topic/libraries/architecture/room) - SQLite object mapping library. |
|
| 51 |
+ - [Jetpack Navigation](https://developer.android.com/guide/navigation) - Navigation refers to the interactions that allow users to navigate across, into, and back out from the different pieces of content within your app |
|
| 52 |
+- [DataStore](https://developer.android.com/topic/libraries/architecture/datastore) - Jetpack DataStore is a data storage solution that allows you to store key-value pairs or typed objects with protocol buffers. DataStore uses Kotlin coroutines and Flow to store data asynchronously, consistently, and transactionally. |
|
| 53 |
+<!-- - [Stateflow](https://developer.android.com/kotlin/flow/stateflow-and-sharedflow) - StateFlow is a state-holder observable flow that emits the current and new state updates to its collectors. |
|
| 54 |
+ - [Flow](https://kotlinlang.org/docs/reference/coroutines/flow.html) - A flow is an asynchronous version of a Sequence, a type of collection whose values are lazily produced. --> |
|
| 55 |
+- [Material Components for Android](https://github.com/material-components/material-components-android) - Modular and customizable Material Design UI components for Android. |
|
| 56 |
+- [Coil for Image loading](https://github.com/coil-kt/coil) - Kotlin based library for loading images in Android. |
|
| 57 |
+- [Dagger Hilt](https://github.com/google/dagger/tree/master/java/dagger/hilt) - Hilt provides a standard way to incorporate Dagger dependency injection into an Android application. For more information. |
|
| 58 |
+- [Easy permissions](https://github.com/vmadalin/easypermissions-ktx) - 🔓 Kotlin version of the popular google/easypermissions wrapper library to simplify basic system permissions logic on Android M or higher. |
|
| 59 |
+- [TimerX](https://github.com/arsvechkarev/TimerX) - Android timer and stopwatch library. |
|
| 60 |
+ |
|
| 61 |
+<!-- <br /> |
|
| 62 |
+ |
|
| 63 |
+## Package Structure 📦 |
|
| 64 |
+ |
|
| 65 |
+ dev.spikeysanju.expenso # Root Package |
|
| 66 |
+ ├── di # Hilt DI Modules |
|
| 67 |
+ ├── data # For data handling. |
|
| 68 |
+ │ ├── local # Local Persistence Database. Room (SQLite) database |
|
| 69 |
+ | │ ├── dao # Data Access Object for Room |
|
| 70 |
+ | | |── database # Database Instance |
|
| 71 |
+ | |
|
| 72 |
+ ├── model # Model classes [Transaction] |
|
| 73 |
+ | |
|
| 74 |
+ |-- repo # Used to handle all data operations |
|
| 75 |
+ | |
|
| 76 |
+ ├── view # Activity/Fragment View layer |
|
| 77 |
+ │ ├── main # Main root folder |
|
| 78 |
+ | │ ├── main # Main Activity for RecyclerView |
|
| 79 |
+ | │ └── viewmodel # Transaction ViewModel |
|
| 80 |
+ | │ ├── adapter # Adapter for RecyclerView |
|
| 81 |
+ │ ├── Dashboard # Dashboard root folder |
|
| 82 |
+ | | |__ dashboard # Dashboard |
|
| 83 |
+ │ ├── Add # Add Transaction root folder |
|
| 84 |
+ | | |__ add # Add Transaction |
|
| 85 |
+ │ ├── Edit # Edit Transaction root folder |
|
| 86 |
+ | | |__ edit # Edit Transaction |
|
| 87 |
+ │ ├── Details # Add Transaction root folder |
|
| 88 |
+ | | |__ details # Transaction Details |
|
| 89 |
+ │ ├── About # About root folder |
|
| 90 |
+ | | |__ about # About |
|
| 91 |
+ │ ├── Dialog # All Dialogs root folder |
|
| 92 |
+ | | |__ dialog # Error Dialog |
|
| 93 |
+ ├── utils # All extension functions |
|
| 94 |
+ |
|
| 95 |
+ |
|
| 96 |
+<br /> |
|
| 97 |
+ --> |
|
| 98 |
+ |
|
| 99 |
+## Architecture 🗼 |
|
| 100 |
+This app uses [***MVVM (Model View View-Model)***](https://developer.android.com/jetpack/docs/guide#recommended-app-arch) architecture. |
|
| 101 |
+ |
|
| 102 |
+ |
|
| 103 |
+ |
|
| 104 |
+## Build-tool 🧰 |
|
| 105 |
+You need to have [Android Studio](https://developer.android.com/studio) to build this project. |
|
| 106 |
+ |
|
| 107 |
+<br /> |
|
| 108 |
+ |
|
| 109 |
+## Credit 🙌 |
|
| 110 |
+Credit goes to [Shazomii's Notely](https://github.com/shazomii/Notely) for project inspiration |
|
| 111 |
+ |
|
| 112 |
+<br /> |
|
| 113 |
+ |
|
| 114 |
+## Contribute 🤝 |
|
| 115 |
+If you want to contribute to this app, you're always welcome! |
|
| 116 |
+See [Contributing Guidelines](https://github.com/certified84/AudioNote/blob/master/CONTRIBUTING.md). |
|
| 117 |
+ |
|
| 118 |
+<br> |
|
| 119 |
+ |
|
| 120 |
+## Contact 📩 |
|
| 121 |
+Have a project? DM us at 👇 |
|
| 122 |
+ |
|
| 123 |
+Drop a mail to:- achiagasamson5@gmail.com |
|
| 124 |
+ |
|
| 125 |
+<br> |
|
| 126 |
+ |
|
| 127 |
+## Donation 💰 |
|
| 128 |
+If this project help you reduce time to develop, you can give me a cup of coffee :) |
|
| 129 |
+ |
|
| 130 |
+<a href="https://www.buymeacoffee.com/SammieKt" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a> |
|
| 131 |
+ |
|
| 132 |
+## License 🔖 |
|
| 133 |
+``` |
|
| 134 |
+ Apache 2.0 License |
|
| 135 |
+ |
|
| 136 |
+ |
|
| 137 |
+ Copyright 2023 Samson Achiaga |
|
| 138 |
+ |
|
| 139 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 140 |
+ you may not use this file except in compliance with the License. |
|
| 141 |
+ You may obtain a copy of the License at |
|
| 142 |
+ |
|
| 143 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 144 |
+ |
|
| 145 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 146 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 147 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 148 |
+ See the License for the specific language governing permissions and |
|
| 149 |
+ limitations under the License. |
|
| 150 |
+ |
|
| 151 |
+``` |
|
| 152 |
+ |
| 1 | 3 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,141 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+plugins {
|
|
| 18 |
+ id("com.android.application")
|
|
| 19 |
+ kotlin("android")
|
|
| 20 |
+ id("kotlin-kapt")
|
|
| 21 |
+ id("kotlin-parcelize")
|
|
| 22 |
+ id("dagger.hilt.android.plugin")
|
|
| 23 |
+ id("androidx.navigation.safeargs.kotlin")
|
|
| 24 |
+ id("com.google.devtools.ksp")
|
|
| 25 |
+ id("org.jetbrains.kotlin.plugin.compose") version "2.1.0"
|
|
| 26 |
+ kotlin("plugin.serialization") version "2.1.0"
|
|
| 27 |
+} |
|
| 28 |
+ |
|
| 29 |
+android {
|
|
| 30 |
+ compileSdk = 35 |
|
| 31 |
+ namespace = "com.certified.audionote" |
|
| 32 |
+ |
|
| 33 |
+ defaultConfig {
|
|
| 34 |
+ applicationId = "com.certified.audionote" |
|
| 35 |
+ minSdk = 21 |
|
| 36 |
+ targetSdk = 35 |
|
| 37 |
+ versionCode = 7 |
|
| 38 |
+ versionName = "0.1.5.2" |
|
| 39 |
+ |
|
| 40 |
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" |
|
| 41 |
+ |
|
| 42 |
+ ksp {
|
|
| 43 |
+ arg("generateKotlin", "true")
|
|
| 44 |
+ } |
|
| 45 |
+ } |
|
| 46 |
+ |
|
| 47 |
+ buildTypes {
|
|
| 48 |
+ release {
|
|
| 49 |
+ isMinifyEnabled = false |
|
| 50 |
+ isShrinkResources = false |
|
| 51 |
+ proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
|
| 52 |
+ } |
|
| 53 |
+ } |
|
| 54 |
+ |
|
| 55 |
+ compileOptions {
|
|
| 56 |
+ sourceCompatibility = JavaVersion.VERSION_17 |
|
| 57 |
+ targetCompatibility = JavaVersion.VERSION_17 |
|
| 58 |
+ } |
|
| 59 |
+ |
|
| 60 |
+ kotlinOptions {
|
|
| 61 |
+ jvmTarget = "17" |
|
| 62 |
+ } |
|
| 63 |
+ |
|
| 64 |
+ buildFeatures {
|
|
| 65 |
+ dataBinding = true |
|
| 66 |
+ viewBinding = true |
|
| 67 |
+ compose = true |
|
| 68 |
+ } |
|
| 69 |
+} |
|
| 70 |
+ |
|
| 71 |
+dependencies {
|
|
| 72 |
+ |
|
| 73 |
+ implementation("androidx.core:core-ktx:1.15.0")
|
|
| 74 |
+ implementation("androidx.appcompat:appcompat:1.7.0")
|
|
| 75 |
+ implementation("com.google.android.material:material:1.12.0")
|
|
| 76 |
+ implementation("androidx.constraintlayout:constraintlayout:2.2.0")
|
|
| 77 |
+ implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
|
|
| 78 |
+ implementation("androidx.navigation:navigation-fragment-ktx:2.8.5")
|
|
| 79 |
+ implementation("androidx.navigation:navigation-ui-ktx:2.8.5")
|
|
| 80 |
+ implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
|
| 81 |
+ implementation("androidx.preference:preference-ktx:1.2.1")
|
|
| 82 |
+ implementation("androidx.work:work-runtime-ktx:2.10.0")
|
|
| 83 |
+ implementation("androidx.core:core-splashscreen:1.0.1")
|
|
| 84 |
+ |
|
| 85 |
+ // Compose |
|
| 86 |
+ implementation(platform("androidx.compose:compose-bom:2024.12.01"))
|
|
| 87 |
+ implementation("androidx.compose.material3:material3")
|
|
| 88 |
+ implementation("androidx.compose.material:material-icons-extended:1.7.6")
|
|
| 89 |
+ implementation("androidx.compose.ui:ui-tooling-preview")
|
|
| 90 |
+ debugImplementation("androidx.compose.ui:ui-tooling")
|
|
| 91 |
+ implementation("androidx.activity:activity-compose:1.9.3")
|
|
| 92 |
+ implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7")
|
|
| 93 |
+ implementation("androidx.navigation:navigation-compose:2.8.5")
|
|
| 94 |
+ |
|
| 95 |
+ // Intuit ssp/sdp |
|
| 96 |
+ implementation("com.intuit.ssp:ssp-android:1.1.0")
|
|
| 97 |
+ implementation("com.intuit.sdp:sdp-android:1.1.0")
|
|
| 98 |
+ |
|
| 99 |
+ // Coroutines |
|
| 100 |
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
|
|
| 101 |
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
|
|
| 102 |
+ |
|
| 103 |
+ // Room persistence library |
|
| 104 |
+ implementation("androidx.room:room-runtime:2.6.1")
|
|
| 105 |
+ implementation("androidx.room:room-ktx:2.6.1")
|
|
| 106 |
+ ksp("androidx.room:room-compiler:2.6.1")
|
|
| 107 |
+ |
|
| 108 |
+ // Datastore |
|
| 109 |
+ implementation("androidx.datastore:datastore-preferences:1.1.1")
|
|
| 110 |
+ |
|
| 111 |
+ // Hilt |
|
| 112 |
+ implementation("com.google.dagger:hilt-android:2.53.1")
|
|
| 113 |
+ ksp("com.google.dagger:hilt-compiler:2.53.1")
|
|
| 114 |
+ ksp("androidx.hilt:hilt-compiler:1.2.0")
|
|
| 115 |
+ implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
|
|
| 116 |
+ |
|
| 117 |
+ // TimerX |
|
| 118 |
+ implementation("com.github.arsvechkarev:TimerX:3.1.0")
|
|
| 119 |
+ |
|
| 120 |
+ // Serilization |
|
| 121 |
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
|
|
| 122 |
+ |
|
| 123 |
+ // Page indicator |
|
| 124 |
+ implementation("com.github.romandanylyk:PageIndicatorView:v.1.0.3")
|
|
| 125 |
+ |
|
| 126 |
+ // Window |
|
| 127 |
+ implementation("androidx.window:window:1.3.0")
|
|
| 128 |
+ |
|
| 129 |
+ // Integration testing |
|
| 130 |
+ androidTestImplementation("androidx.test.ext:junit:1.2.1")
|
|
| 131 |
+ androidTestImplementation("com.google.truth:truth:1.1.3")
|
|
| 132 |
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
|
| 133 |
+ androidTestImplementation(platform("androidx.compose:compose-bom:2024.12.01"))
|
|
| 134 |
+ androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
|
| 135 |
+ debugImplementation("androidx.compose.ui:ui-test-manifest")
|
|
| 136 |
+ |
|
| 137 |
+ // Unit testing |
|
| 138 |
+ testImplementation("junit:junit:4.13.2")
|
|
| 139 |
+ testImplementation("com.google.truth:truth:1.1.3")
|
|
| 140 |
+ testImplementation("androidx.room:room-testing:2.6.1")
|
|
| 141 |
+} |
|
| 0 | 142 |
\ No newline at end of file |
| 1 | 143 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 1 |
+# Add project specific ProGuard rules here. |
|
| 2 |
+# You can control the set of applied configuration files using the |
|
| 3 |
+# proguardFiles setting in build.gradle.kts. |
|
| 4 |
+# |
|
| 5 |
+# For more details, see |
|
| 6 |
+# http://developer.android.com/guide/developing/tools/proguard.html |
|
| 7 |
+ |
|
| 8 |
+# If your project uses WebView with JS, uncomment the following |
|
| 9 |
+# and specify the fully qualified class name to the JavaScript interface |
|
| 10 |
+# class: |
|
| 11 |
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
| 12 |
+# public *; |
|
| 13 |
+#} |
|
| 14 |
+ |
|
| 15 |
+# Uncomment this to preserve the line number information for |
|
| 16 |
+# debugging stack traces. |
|
| 17 |
+#-keepattributes SourceFile,LineNumberTable |
|
| 18 |
+ |
|
| 19 |
+# If you keep the line number information, uncomment this to |
|
| 20 |
+# hide the original source file name. |
|
| 21 |
+#-renamesourcefileattribute SourceFile |
|
| 0 | 22 |
\ No newline at end of file |
| 3 | 25 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,20 @@ |
| 1 |
+{
|
|
| 2 |
+ "version": 3, |
|
| 3 |
+ "artifactType": {
|
|
| 4 |
+ "type": "APK", |
|
| 5 |
+ "kind": "Directory" |
|
| 6 |
+ }, |
|
| 7 |
+ "applicationId": "com.certified.audionote", |
|
| 8 |
+ "variantName": "release", |
|
| 9 |
+ "elements": [ |
|
| 10 |
+ {
|
|
| 11 |
+ "type": "SINGLE", |
|
| 12 |
+ "filters": [], |
|
| 13 |
+ "attributes": [], |
|
| 14 |
+ "versionCode": 7, |
|
| 15 |
+ "versionName": "0.1.5.2", |
|
| 16 |
+ "outputFile": "app-release.apk" |
|
| 17 |
+ } |
|
| 18 |
+ ], |
|
| 19 |
+ "elementType": "File" |
|
| 20 |
+} |
|
| 0 | 21 |
\ No newline at end of file |
| 1 | 22 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,40 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote |
|
| 18 |
+ |
|
| 19 |
+import androidx.test.platform.app.InstrumentationRegistry |
|
| 20 |
+import androidx.test.ext.junit.runners.AndroidJUnit4 |
|
| 21 |
+ |
|
| 22 |
+import org.junit.Test |
|
| 23 |
+import org.junit.runner.RunWith |
|
| 24 |
+ |
|
| 25 |
+import org.junit.Assert.* |
|
| 26 |
+ |
|
| 27 |
+/** |
|
| 28 |
+ * Instrumented test, which will execute on an Android device. |
|
| 29 |
+ * |
|
| 30 |
+ * See [testing documentation](http://d.android.com/tools/testing). |
|
| 31 |
+ */ |
|
| 32 |
+@RunWith(AndroidJUnit4::class) |
|
| 33 |
+class ExampleInstrumentedTest {
|
|
| 34 |
+ @Test |
|
| 35 |
+ fun useAppContext() {
|
|
| 36 |
+ // Context of the app under test. |
|
| 37 |
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext |
|
| 38 |
+ assertEquals("com.certified.audionote", appContext.packageName)
|
|
| 39 |
+ } |
|
| 40 |
+} |
|
| 0 | 41 |
\ No newline at end of file |
| 1 | 42 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,55 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 18 |
+ |
|
| 19 |
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> |
|
| 20 |
+ <uses-permission android:name="android.permission.RECORD_AUDIO" /> |
|
| 21 |
+ <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> |
|
| 22 |
+ <uses-permission android:name="android.permission.VIBRATE" /> |
|
| 23 |
+ |
|
| 24 |
+ <application |
|
| 25 |
+ android:name=".AudioNotesApp" |
|
| 26 |
+ android:allowBackup="true" |
|
| 27 |
+ android:icon="@mipmap/ic_logo" |
|
| 28 |
+ android:label="@string/app_name" |
|
| 29 |
+ android:roundIcon="@mipmap/ic_logo_round" |
|
| 30 |
+ android:supportsRtl="true" |
|
| 31 |
+ android:theme="@style/Theme.AudioNote"> |
|
| 32 |
+ <activity |
|
| 33 |
+ android:name=".ui.main.MainActivity" |
|
| 34 |
+ android:exported="true"> |
|
| 35 |
+ <intent-filter> |
|
| 36 |
+ <action android:name="android.intent.action.MAIN" /> |
|
| 37 |
+ |
|
| 38 |
+ <category android:name="android.intent.category.LAUNCHER" /> |
|
| 39 |
+ </intent-filter> |
|
| 40 |
+ </activity> |
|
| 41 |
+ <receiver android:name=".ui.AlertReceiver" /> |
|
| 42 |
+ |
|
| 43 |
+ <provider |
|
| 44 |
+ android:name="androidx.core.content.FileProvider" |
|
| 45 |
+ android:authorities="com.certified.audionote.provider" |
|
| 46 |
+ android:exported="false" |
|
| 47 |
+ android:grantUriPermissions="true"> |
|
| 48 |
+ <meta-data |
|
| 49 |
+ android:name="android.support.FILE_PROVIDER_PATHS" |
|
| 50 |
+ android:resource="@xml/file_paths"> |
|
| 51 |
+ </meta-data> |
|
| 52 |
+ </provider> |
|
| 53 |
+ </application> |
|
| 54 |
+ |
|
| 55 |
+</manifest> |
|
| 0 | 56 |
\ No newline at end of file |
| 3 | 59 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,23 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote |
|
| 18 |
+ |
|
| 19 |
+import android.app.Application |
|
| 20 |
+import dagger.hilt.android.HiltAndroidApp |
|
| 21 |
+ |
|
| 22 |
+@HiltAndroidApp |
|
| 23 |
+class AudioNotesApp : Application() |
|
| 0 | 24 |
\ No newline at end of file |
| 1 | 25 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,79 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.adapter |
|
| 18 |
+ |
|
| 19 |
+import android.graphics.Paint |
|
| 20 |
+import android.view.View |
|
| 21 |
+import android.widget.ImageView |
|
| 22 |
+import android.widget.TextView |
|
| 23 |
+import androidx.databinding.BindingAdapter |
|
| 24 |
+import androidx.recyclerview.widget.RecyclerView |
|
| 25 |
+import com.certified.audionote.model.Note |
|
| 26 |
+ |
|
| 27 |
+@BindingAdapter("listItems")
|
|
| 28 |
+fun bindItemRecyclerView(recyclerView: RecyclerView, data: List<Note>?) {
|
|
| 29 |
+ val adapter = recyclerView.adapter as NoteRecyclerAdapter |
|
| 30 |
+ adapter.submitList(data) |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+@BindingAdapter("visible")
|
|
| 34 |
+fun View.setVisible(visible: Boolean) {
|
|
| 35 |
+ visibility = if (visible) View.VISIBLE else View.GONE |
|
| 36 |
+} |
|
| 37 |
+ |
|
| 38 |
+@BindingAdapter("editNoteVisible")
|
|
| 39 |
+fun View.setEditNoteVisible(audioLength: Long) {
|
|
| 40 |
+ visibility = when (audioLength) {
|
|
| 41 |
+ 0L -> View.GONE |
|
| 42 |
+ else -> View.VISIBLE |
|
| 43 |
+ } |
|
| 44 |
+} |
|
| 45 |
+ |
|
| 46 |
+@BindingAdapter("timerVisible")
|
|
| 47 |
+fun View.setTimerVisible(audioLength: Long) {
|
|
| 48 |
+ visibility = when (audioLength) {
|
|
| 49 |
+ 0L -> View.GONE |
|
| 50 |
+ else -> View.VISIBLE |
|
| 51 |
+ } |
|
| 52 |
+} |
|
| 53 |
+ |
|
| 54 |
+@BindingAdapter("strikeThrough")
|
|
| 55 |
+fun strikeThrough(textView: TextView, strikeThrough: Boolean) {
|
|
| 56 |
+ if (strikeThrough) {
|
|
| 57 |
+ textView.paintFlags = Paint.STRIKE_THRU_TEXT_FLAG |
|
| 58 |
+ } else {
|
|
| 59 |
+ textView.paintFlags = 0 |
|
| 60 |
+ } |
|
| 61 |
+} |
|
| 62 |
+ |
|
| 63 |
+@BindingAdapter("timeText")
|
|
| 64 |
+fun TextView.timeText(value: Long) {
|
|
| 65 |
+ text = if (value >= 3600) |
|
| 66 |
+ String.format("%02d:%02d:%02d", value / 3600, (value % 3600) / 60, value % 60)
|
|
| 67 |
+ else |
|
| 68 |
+ String.format("%02d:%02d", (value % 3600) / 60, value % 60)
|
|
| 69 |
+} |
|
| 70 |
+ |
|
| 71 |
+@BindingAdapter("image")
|
|
| 72 |
+fun ImageView.loadImage(image: Int) {
|
|
| 73 |
+ setImageResource(image) |
|
| 74 |
+} |
|
| 75 |
+ |
|
| 76 |
+@BindingAdapter("sizeText")
|
|
| 77 |
+fun TextView.sizeText(value: String) {
|
|
| 78 |
+ text = "${value}MB"
|
|
| 79 |
+} |
|
| 0 | 80 |
\ No newline at end of file |
| 1 | 81 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,63 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.adapter |
|
| 18 |
+ |
|
| 19 |
+import android.view.LayoutInflater |
|
| 20 |
+import android.view.ViewGroup |
|
| 21 |
+import androidx.recyclerview.widget.DiffUtil |
|
| 22 |
+import androidx.recyclerview.widget.ListAdapter |
|
| 23 |
+import androidx.recyclerview.widget.RecyclerView |
|
| 24 |
+import com.certified.audionote.databinding.ItemNoteBinding |
|
| 25 |
+import com.certified.audionote.model.Note |
|
| 26 |
+ |
|
| 27 |
+class NoteRecyclerAdapter(private val onItemClick: (note: Note) -> Unit) : |
|
| 28 |
+ ListAdapter<Note, NoteRecyclerAdapter.ViewHolder>(DIFF_CALLBACK) {
|
|
| 29 |
+ |
|
| 30 |
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
| 31 |
+ val binding = |
|
| 32 |
+ ItemNoteBinding.inflate(LayoutInflater.from(parent.context), parent, false) |
|
| 33 |
+ return ViewHolder(binding) |
|
| 34 |
+ } |
|
| 35 |
+ |
|
| 36 |
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
| 37 |
+ val currentItem = getItem(position) |
|
| 38 |
+ holder.bind(currentItem) |
|
| 39 |
+ } |
|
| 40 |
+ |
|
| 41 |
+ inner class ViewHolder(private val binding: ItemNoteBinding) : |
|
| 42 |
+ RecyclerView.ViewHolder(binding.root) {
|
|
| 43 |
+ |
|
| 44 |
+ fun bind(note: Note) {
|
|
| 45 |
+ binding.note = note |
|
| 46 |
+ } |
|
| 47 |
+ |
|
| 48 |
+ init {
|
|
| 49 |
+ itemView.setOnClickListener {
|
|
| 50 |
+ val position = adapterPosition |
|
| 51 |
+ if (position != RecyclerView.NO_POSITION) |
|
| 52 |
+ onItemClick.invoke(getItem(position)) |
|
| 53 |
+ } |
|
| 54 |
+ } |
|
| 55 |
+ } |
|
| 56 |
+ |
|
| 57 |
+ companion object {
|
|
| 58 |
+ val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Note>() {
|
|
| 59 |
+ override fun areItemsTheSame(oldItem: Note, newItem: Note) = oldItem.id == newItem.id |
|
| 60 |
+ override fun areContentsTheSame(oldItem: Note, newItem: Note) = oldItem == newItem |
|
| 61 |
+ } |
|
| 62 |
+ } |
|
| 63 |
+} |
|
| 0 | 64 |
\ No newline at end of file |
| 1 | 65 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,55 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.adapter |
|
| 18 |
+ |
|
| 19 |
+import android.view.LayoutInflater |
|
| 20 |
+import android.view.ViewGroup |
|
| 21 |
+import androidx.recyclerview.widget.DiffUtil |
|
| 22 |
+import androidx.recyclerview.widget.ListAdapter |
|
| 23 |
+import androidx.recyclerview.widget.RecyclerView |
|
| 24 |
+import com.certified.audionote.databinding.ItemSliderBinding |
|
| 25 |
+import com.certified.audionote.model.SliderItem |
|
| 26 |
+ |
|
| 27 |
+class ViewPagerAdapter() : |
|
| 28 |
+ ListAdapter<SliderItem, ViewPagerAdapter.ViewHolder>(DIFF_CALLBACK) {
|
|
| 29 |
+ |
|
| 30 |
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
| 31 |
+ val binding = ItemSliderBinding.inflate(LayoutInflater.from(parent.context), parent, false) |
|
| 32 |
+ return ViewHolder(binding) |
|
| 33 |
+ } |
|
| 34 |
+ |
|
| 35 |
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
| 36 |
+ val currentItem = getItem(position) |
|
| 37 |
+ holder.bind(currentItem) |
|
| 38 |
+ } |
|
| 39 |
+ |
|
| 40 |
+ inner class ViewHolder(val binding: ItemSliderBinding) : RecyclerView.ViewHolder(binding.root) {
|
|
| 41 |
+ fun bind(sliderItem: SliderItem) {
|
|
| 42 |
+ binding.sliderItem = sliderItem |
|
| 43 |
+ } |
|
| 44 |
+ } |
|
| 45 |
+ |
|
| 46 |
+ companion object {
|
|
| 47 |
+ val DIFF_CALLBACK = object : DiffUtil.ItemCallback<SliderItem>() {
|
|
| 48 |
+ override fun areItemsTheSame(oldItem: SliderItem, newItem: SliderItem) = |
|
| 49 |
+ oldItem.title == newItem.title |
|
| 50 |
+ |
|
| 51 |
+ override fun areContentsTheSame(oldItem: SliderItem, newItem: SliderItem) = |
|
| 52 |
+ oldItem == newItem |
|
| 53 |
+ } |
|
| 54 |
+ } |
|
| 55 |
+} |
|
| 0 | 56 |
\ No newline at end of file |
| 1 | 57 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,40 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.database |
|
| 18 |
+ |
|
| 19 |
+import androidx.room.* |
|
| 20 |
+import com.certified.audionote.model.Note |
|
| 21 |
+import kotlinx.coroutines.flow.Flow |
|
| 22 |
+ |
|
| 23 |
+@Dao |
|
| 24 |
+interface AudioNotesDAO {
|
|
| 25 |
+ |
|
| 26 |
+ @Insert(onConflict = OnConflictStrategy.REPLACE) |
|
| 27 |
+ suspend fun insertNote(note: Note) |
|
| 28 |
+ |
|
| 29 |
+ @Update |
|
| 30 |
+ suspend fun updateNote(note: Note) |
|
| 31 |
+ |
|
| 32 |
+ @Delete |
|
| 33 |
+ suspend fun deleteNote(note: Note) |
|
| 34 |
+ |
|
| 35 |
+ @Query("SELECT * FROM notes_table WHERE id = :noteId")
|
|
| 36 |
+ fun getNote(noteId: Int): Flow<Note> |
|
| 37 |
+ |
|
| 38 |
+ @Query("SELECT * FROM notes_table ORDER BY id DESC")
|
|
| 39 |
+ fun getAllNotes(): Flow<List<Note>?> |
|
| 40 |
+} |
|
| 0 | 41 |
\ No newline at end of file |
| 1 | 42 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,30 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.database |
|
| 18 |
+ |
|
| 19 |
+import androidx.room.Database |
|
| 20 |
+import androidx.room.RoomDatabase |
|
| 21 |
+import androidx.room.TypeConverters |
|
| 22 |
+import com.certified.audionote.model.Note |
|
| 23 |
+import com.certified.audionote.utils.Converters |
|
| 24 |
+ |
|
| 25 |
+@Database(entities = [Note::class], version = 1, exportSchema = false) |
|
| 26 |
+@TypeConverters(Converters::class) |
|
| 27 |
+abstract class AudioNotesDatabase : RoomDatabase() {
|
|
| 28 |
+ |
|
| 29 |
+ abstract fun audioNotesDao(): AudioNotesDAO |
|
| 30 |
+} |
|
| 0 | 31 |
\ No newline at end of file |
| 1 | 32 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,35 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.di |
|
| 18 |
+ |
|
| 19 |
+import android.app.Application |
|
| 20 |
+import android.content.Context |
|
| 21 |
+import dagger.Module |
|
| 22 |
+import dagger.Provides |
|
| 23 |
+import dagger.hilt.InstallIn |
|
| 24 |
+import dagger.hilt.android.components.ActivityRetainedComponent |
|
| 25 |
+import dagger.hilt.android.qualifiers.ApplicationContext |
|
| 26 |
+ |
|
| 27 |
+@InstallIn(ActivityRetainedComponent::class) |
|
| 28 |
+@Module |
|
| 29 |
+object ApplicationModule {
|
|
| 30 |
+ |
|
| 31 |
+ @Provides |
|
| 32 |
+ fun provideAppContext(@ApplicationContext context: Application): Context {
|
|
| 33 |
+ return context.applicationContext |
|
| 34 |
+ } |
|
| 35 |
+} |
|
| 0 | 36 |
\ No newline at end of file |
| 1 | 37 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,46 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.di |
|
| 18 |
+ |
|
| 19 |
+import android.content.Context |
|
| 20 |
+import androidx.room.Room |
|
| 21 |
+import com.certified.audionote.database.AudioNotesDAO |
|
| 22 |
+import com.certified.audionote.database.AudioNotesDatabase |
|
| 23 |
+import dagger.Module |
|
| 24 |
+import dagger.Provides |
|
| 25 |
+import dagger.hilt.InstallIn |
|
| 26 |
+import dagger.hilt.android.qualifiers.ApplicationContext |
|
| 27 |
+import dagger.hilt.components.SingletonComponent |
|
| 28 |
+import javax.inject.Singleton |
|
| 29 |
+ |
|
| 30 |
+@InstallIn(SingletonComponent::class) |
|
| 31 |
+@Module |
|
| 32 |
+class DatabaseModule {
|
|
| 33 |
+ |
|
| 34 |
+ @Singleton |
|
| 35 |
+ @Provides |
|
| 36 |
+ fun provideAudioNotesDatabase(@ApplicationContext context: Context) = |
|
| 37 |
+ Room.databaseBuilder(context, AudioNotesDatabase::class.java, "audio_notes_database.db") |
|
| 38 |
+ .fallbackToDestructiveMigration() |
|
| 39 |
+ .build() |
|
| 40 |
+ |
|
| 41 |
+ @Singleton |
|
| 42 |
+ @Provides |
|
| 43 |
+ fun provideNoteDao(database: AudioNotesDatabase): AudioNotesDAO {
|
|
| 44 |
+ return database.audioNotesDao() |
|
| 45 |
+ } |
|
| 46 |
+} |
|
| 0 | 47 |
\ No newline at end of file |
| 1 | 48 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,67 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.features.settings |
|
| 18 |
+ |
|
| 19 |
+import android.os.Bundle |
|
| 20 |
+import android.view.LayoutInflater |
|
| 21 |
+import android.view.View |
|
| 22 |
+import android.view.ViewGroup |
|
| 23 |
+import androidx.fragment.app.Fragment |
|
| 24 |
+import androidx.navigation.NavController |
|
| 25 |
+import androidx.navigation.Navigation |
|
| 26 |
+import com.certified.audionote.R |
|
| 27 |
+import com.certified.audionote.databinding.FragmentSettingsBinding |
|
| 28 |
+import com.certified.audionote.utils.Extensions.flags |
|
| 29 |
+import com.certified.audionote.utils.Extensions.safeNavigate |
|
| 30 |
+ |
|
| 31 |
+class SettingsFragment : Fragment() {
|
|
| 32 |
+ |
|
| 33 |
+ private var _binding: FragmentSettingsBinding? = null |
|
| 34 |
+ private val binding get() = _binding!! |
|
| 35 |
+ private lateinit var navController: NavController |
|
| 36 |
+ |
|
| 37 |
+ override fun onCreateView( |
|
| 38 |
+ inflater: LayoutInflater, |
|
| 39 |
+ container: ViewGroup?, |
|
| 40 |
+ savedInstanceState: Bundle? |
|
| 41 |
+ ): View {
|
|
| 42 |
+ // Inflate the layout for this fragment |
|
| 43 |
+ _binding = FragmentSettingsBinding.inflate(inflater, container, false) |
|
| 44 |
+ return binding.root |
|
| 45 |
+ } |
|
| 46 |
+ |
|
| 47 |
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
| 48 |
+ super.onViewCreated(view, savedInstanceState) |
|
| 49 |
+ |
|
| 50 |
+ navController = Navigation.findNavController(view) |
|
| 51 |
+ |
|
| 52 |
+ binding.apply {
|
|
| 53 |
+ btnBack.setOnClickListener { navController.safeNavigate(SettingsFragmentDirections.actionSettingsFragmentToHomeFragment()) }
|
|
| 54 |
+ groupAbout.setOnClickListener { navController.safeNavigate(SettingsFragmentDirections.actionSettingsFragmentToAboutFragment()) }
|
|
| 55 |
+ } |
|
| 56 |
+ } |
|
| 57 |
+ |
|
| 58 |
+ override fun onResume() {
|
|
| 59 |
+ super.onResume() |
|
| 60 |
+ flags(R.color.fragment_background) |
|
| 61 |
+ } |
|
| 62 |
+ |
|
| 63 |
+ override fun onDestroyView() {
|
|
| 64 |
+ super.onDestroyView() |
|
| 65 |
+ _binding = null |
|
| 66 |
+ } |
|
| 67 |
+} |
|
| 0 | 68 |
\ No newline at end of file |
| 1 | 69 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,191 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.features.settings |
|
| 18 |
+ |
|
| 19 |
+import android.content.res.* |
|
| 20 |
+import androidx.compose.foundation.* |
|
| 21 |
+import androidx.compose.foundation.layout.* |
|
| 22 |
+import androidx.compose.foundation.shape.* |
|
| 23 |
+import androidx.compose.material.icons.* |
|
| 24 |
+import androidx.compose.material.icons.automirrored.outlined.* |
|
| 25 |
+import androidx.compose.material.icons.outlined.* |
|
| 26 |
+import androidx.compose.material3.* |
|
| 27 |
+import androidx.compose.runtime.* |
|
| 28 |
+import androidx.compose.ui.* |
|
| 29 |
+import androidx.compose.ui.draw.* |
|
| 30 |
+import androidx.compose.ui.graphics.vector.* |
|
| 31 |
+import androidx.compose.ui.res.* |
|
| 32 |
+import androidx.compose.ui.text.* |
|
| 33 |
+import androidx.compose.ui.tooling.preview.* |
|
| 34 |
+import androidx.compose.ui.unit.* |
|
| 35 |
+import com.certified.audionote.R |
|
| 36 |
+import com.certified.audionote.ui.theme.* |
|
| 37 |
+ |
|
| 38 |
+/** |
|
| 39 |
+ * Created by MJ Jacobs on 2024/12/28 at 14:54 |
|
| 40 |
+ */ |
|
| 41 |
+ |
|
| 42 |
+@Composable |
|
| 43 |
+fun SettingsScreen( |
|
| 44 |
+ modifier: Modifier = Modifier |
|
| 45 |
+) {
|
|
| 46 |
+ SettingsScreenContent( |
|
| 47 |
+ modifier = modifier |
|
| 48 |
+ ) |
|
| 49 |
+} |
|
| 50 |
+ |
|
| 51 |
+@Composable |
|
| 52 |
+private fun SettingsScreenContent( |
|
| 53 |
+ modifier: Modifier = Modifier |
|
| 54 |
+) {
|
|
| 55 |
+ Column( |
|
| 56 |
+ modifier = modifier.fillMaxSize(), |
|
| 57 |
+ content = {
|
|
| 58 |
+ // Display title |
|
| 59 |
+ Text( |
|
| 60 |
+ modifier = Modifier |
|
| 61 |
+ .fillMaxWidth() |
|
| 62 |
+ .padding(start = largePadding + 24.dp), |
|
| 63 |
+ text = stringResource(R.string.display), |
|
| 64 |
+ style = TextStyle( |
|
| 65 |
+ color = if (isSystemInDarkTheme()) primaryDark else primaryLight, |
|
| 66 |
+ fontSize = 20.sp |
|
| 67 |
+ ) |
|
| 68 |
+ ) |
|
| 69 |
+ Spacer(modifier = Modifier.height(normalPadding)) |
|
| 70 |
+ |
|
| 71 |
+ // Theme selection |
|
| 72 |
+ SettingsRowItem( |
|
| 73 |
+ icon = Icons.Outlined.BrightnessMedium, |
|
| 74 |
+ imageDescription = stringResource(R.string.theme), |
|
| 75 |
+ title = stringResource(R.string.theme), |
|
| 76 |
+ description = stringResource(R.string.theme_system_default), |
|
| 77 |
+ onClick = { /*TODO*/ }
|
|
| 78 |
+ ) |
|
| 79 |
+ Spacer(modifier = Modifier.height(normalPadding)) |
|
| 80 |
+ // About title |
|
| 81 |
+ Text( |
|
| 82 |
+ modifier = Modifier |
|
| 83 |
+ .fillMaxWidth() |
|
| 84 |
+ .padding(start = largePadding + 24.dp), |
|
| 85 |
+ text = stringResource(R.string.about), |
|
| 86 |
+ style = TextStyle( |
|
| 87 |
+ color = if (isSystemInDarkTheme()) primaryDark else primaryLight, |
|
| 88 |
+ fontSize = 20.sp |
|
| 89 |
+ ) |
|
| 90 |
+ ) |
|
| 91 |
+ Spacer(modifier = Modifier.height(normalPadding)) |
|
| 92 |
+ |
|
| 93 |
+ // Theme selection |
|
| 94 |
+ SettingsRowItem( |
|
| 95 |
+ icon = Icons.Outlined.Person, |
|
| 96 |
+ imageDescription = stringResource(R.string.developer), |
|
| 97 |
+ title = stringResource(R.string.developer), |
|
| 98 |
+ description = stringResource(R.string.developer_nick), |
|
| 99 |
+ onClick = { /*TODO*/ }
|
|
| 100 |
+ ) |
|
| 101 |
+ Spacer(modifier = Modifier.height(normalPadding)) |
|
| 102 |
+ |
|
| 103 |
+ // Theme selection |
|
| 104 |
+ SettingsRowItem( |
|
| 105 |
+ icon = Icons.Outlined.Code, |
|
| 106 |
+ imageDescription = stringResource(R.string.contribute), |
|
| 107 |
+ title = stringResource(R.string.contribute), |
|
| 108 |
+ description = stringResource(R.string.contribute_summary), |
|
| 109 |
+ onClick = { /*TODO*/ }
|
|
| 110 |
+ ) |
|
| 111 |
+ Spacer(modifier = Modifier.height(normalPadding)) |
|
| 112 |
+ |
|
| 113 |
+ // Theme selection |
|
| 114 |
+ SettingsRowItem( |
|
| 115 |
+ icon = Icons.AutoMirrored.Outlined.ContactSupport, |
|
| 116 |
+ imageDescription = stringResource(R.string.contact_feedback), |
|
| 117 |
+ title = stringResource(R.string.contact_feedback), |
|
| 118 |
+ description = stringResource(R.string.developer_mail), |
|
| 119 |
+ onClick = { /*TODO*/ }
|
|
| 120 |
+ ) |
|
| 121 |
+ Spacer(modifier = Modifier.height(normalPadding)) |
|
| 122 |
+ |
|
| 123 |
+ // Theme selection |
|
| 124 |
+ SettingsRowItem( |
|
| 125 |
+ icon = Icons.Outlined.Info, |
|
| 126 |
+ imageDescription = stringResource(R.string.about), |
|
| 127 |
+ title = stringResource(R.string.about), |
|
| 128 |
+ description = stringResource(R.string.app_version_licence_and_more), |
|
| 129 |
+ onClick = { /*TODO*/ }
|
|
| 130 |
+ ) |
|
| 131 |
+ Spacer(modifier = Modifier.height(normalPadding)) |
|
| 132 |
+ } |
|
| 133 |
+ ) |
|
| 134 |
+} |
|
| 135 |
+ |
|
| 136 |
+@Composable |
|
| 137 |
+private fun SettingsRowItem( |
|
| 138 |
+ icon: ImageVector, |
|
| 139 |
+ imageDescription: String, |
|
| 140 |
+ title: String, |
|
| 141 |
+ description: String, |
|
| 142 |
+ onClick: () -> Unit, |
|
| 143 |
+) {
|
|
| 144 |
+ Row( |
|
| 145 |
+ modifier = Modifier |
|
| 146 |
+ .fillMaxWidth() |
|
| 147 |
+ .clip(RoundedCornerShape(defaultCornerSize)) |
|
| 148 |
+ .clickable { onClick() },
|
|
| 149 |
+ verticalAlignment = Alignment.CenterVertically, |
|
| 150 |
+ content = {
|
|
| 151 |
+ // Icon |
|
| 152 |
+ Icon( |
|
| 153 |
+ modifier = Modifier.padding(normalPadding), |
|
| 154 |
+ imageVector = icon, |
|
| 155 |
+ contentDescription = imageDescription |
|
| 156 |
+ ) |
|
| 157 |
+ |
|
| 158 |
+ Column( |
|
| 159 |
+ modifier = Modifier.fillMaxWidth(), |
|
| 160 |
+ content = {
|
|
| 161 |
+ // Title text field |
|
| 162 |
+ Text( |
|
| 163 |
+ text = title, |
|
| 164 |
+ style = MaterialTheme.typography.titleMedium |
|
| 165 |
+ ) |
|
| 166 |
+ |
|
| 167 |
+ Text( |
|
| 168 |
+ text = description, |
|
| 169 |
+ style = MaterialTheme.typography.bodyMedium |
|
| 170 |
+ ) |
|
| 171 |
+ } |
|
| 172 |
+ ) |
|
| 173 |
+ } |
|
| 174 |
+ ) |
|
| 175 |
+} |
|
| 176 |
+ |
|
| 177 |
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, showBackground = true) |
|
| 178 |
+@Composable |
|
| 179 |
+private fun PreviewSettingsScreenContentLightTheme() {
|
|
| 180 |
+ AudioNoteTheme {
|
|
| 181 |
+ SettingsScreenContent() |
|
| 182 |
+ } |
|
| 183 |
+} |
|
| 184 |
+ |
|
| 185 |
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, showBackground = true) |
|
| 186 |
+@Composable |
|
| 187 |
+private fun PreviewSettingsScreenContentDarkTheme() {
|
|
| 188 |
+ AudioNoteTheme {
|
|
| 189 |
+ SettingsScreenContent() |
|
| 190 |
+ } |
|
| 191 |
+} |
|
| 0 | 192 |
\ No newline at end of file |
| 1 | 193 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,56 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.model |
|
| 18 |
+ |
|
| 19 |
+import android.os.Parcelable |
|
| 20 |
+import androidx.room.Entity |
|
| 21 |
+import androidx.room.PrimaryKey |
|
| 22 |
+import com.certified.audionote.utils.colors |
|
| 23 |
+import com.certified.audionote.utils.currentDate |
|
| 24 |
+import kotlinx.parcelize.Parcelize |
|
| 25 |
+ |
|
| 26 |
+/** |
|
| 27 |
+ * The Note class represent the domain model i.e the |
|
| 28 |
+ * object visible to the app user. |
|
| 29 |
+ * |
|
| 30 |
+ * @param id id of the note |
|
| 31 |
+ * @param title title of the note |
|
| 32 |
+ * @param description content of the note |
|
| 33 |
+ * @param color color of the note |
|
| 34 |
+ * @param lastModificationDate date the note was created/modified |
|
| 35 |
+ * @param audioLength The length of the audio recording |
|
| 36 |
+ * @param size Basically the size of the audio in MB in the device |
|
| 37 |
+ * @param started whether or note the reminder is active |
|
| 38 |
+ * @param reminder date set for a reminder in the note |
|
| 39 |
+ * |
|
| 40 |
+ **/ |
|
| 41 |
+ |
|
| 42 |
+@Parcelize |
|
| 43 |
+@Entity(tableName = "notes_table") |
|
| 44 |
+data class Note( |
|
| 45 |
+ var title: String = "", |
|
| 46 |
+ var description: String = "", |
|
| 47 |
+ var color: Int = colors.random(), |
|
| 48 |
+ var lastModificationDate: Long = currentDate().timeInMillis, |
|
| 49 |
+ var size: String = "", |
|
| 50 |
+ var audioLength: Long = -1L, |
|
| 51 |
+ var filePath: String = "", |
|
| 52 |
+ var started: Boolean = false, |
|
| 53 |
+ var reminder: Long? = null, |
|
| 54 |
+ @PrimaryKey(autoGenerate = true) |
|
| 55 |
+ var id: Int = 0, |
|
| 56 |
+) : Parcelable |
|
| 0 | 57 |
\ No newline at end of file |
| 1 | 58 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,29 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.model |
|
| 18 |
+ |
|
| 19 |
+/** |
|
| 20 |
+ * The SliderItem class represent a domain model i.e an |
|
| 21 |
+ * object visible to the app user. It is used in conjunction |
|
| 22 |
+ * with ViewPager2 to create the Onboarding |
|
| 23 |
+ * |
|
| 24 |
+ * @param image image of the sliderItem |
|
| 25 |
+ * @param title title of the sliderItem |
|
| 26 |
+ * @param description description of the sliderItem |
|
| 27 |
+ * |
|
| 28 |
+ **/ |
|
| 29 |
+data class SliderItem (val image: Int, val title: String, val description: String) |
|
| 0 | 30 |
\ No newline at end of file |
| 1 | 31 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,78 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.navigation |
|
| 18 |
+ |
|
| 19 |
+import android.app.Activity |
|
| 20 |
+import androidx.compose.foundation.layout.* |
|
| 21 |
+import androidx.compose.material3.* |
|
| 22 |
+import androidx.compose.runtime.* |
|
| 23 |
+import androidx.compose.ui.* |
|
| 24 |
+import androidx.navigation.compose.* |
|
| 25 |
+import com.certified.audionote.navigation.nav_hosts.* |
|
| 26 |
+import com.certified.audionote.ui.theme.* |
|
| 27 |
+import com.certified.audionote.utils.* |
|
| 28 |
+ |
|
| 29 |
+/** |
|
| 30 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:56 |
|
| 31 |
+ */ |
|
| 32 |
+ |
|
| 33 |
+// TODO: 2024/12/28 - Decide on whether to use height or width to measure screen orientation |
|
| 34 |
+ |
|
| 35 |
+@Composable |
|
| 36 |
+fun AudioNoteNavHost( |
|
| 37 |
+ activity: Activity, |
|
| 38 |
+) {
|
|
| 39 |
+ val navController = rememberNavController() |
|
| 40 |
+ |
|
| 41 |
+ Scaffold( |
|
| 42 |
+ content = { paddingValues ->
|
|
| 43 |
+ Box( |
|
| 44 |
+ modifier = Modifier.padding( |
|
| 45 |
+ top = paddingValues.calculateTopPadding().plus(normalPadding), |
|
| 46 |
+ start = normalPadding, |
|
| 47 |
+ end = normalPadding, |
|
| 48 |
+ bottom = paddingValues.calculateBottomPadding().plus(normalPadding) |
|
| 49 |
+ ) |
|
| 50 |
+ ) {
|
|
| 51 |
+ calculateWindowSize( |
|
| 52 |
+ activity = activity, |
|
| 53 |
+ windowWidthSizeClassChange = { windowSize ->
|
|
| 54 |
+ when (windowSize) {
|
|
| 55 |
+ WindowSizeClass.COMPACT -> {
|
|
| 56 |
+ CompactNavHost( |
|
| 57 |
+ navController = navController |
|
| 58 |
+ ) |
|
| 59 |
+ } |
|
| 60 |
+ |
|
| 61 |
+ WindowSizeClass.MEDIUM -> {
|
|
| 62 |
+ MediumNavHost( |
|
| 63 |
+ navController = navController |
|
| 64 |
+ ) |
|
| 65 |
+ } |
|
| 66 |
+ |
|
| 67 |
+ WindowSizeClass.EXPANDED -> {
|
|
| 68 |
+ ExpandedNavHost( |
|
| 69 |
+ navController = navController |
|
| 70 |
+ ) |
|
| 71 |
+ } |
|
| 72 |
+ } |
|
| 73 |
+ } |
|
| 74 |
+ ) |
|
| 75 |
+ } |
|
| 76 |
+ } |
|
| 77 |
+ ) |
|
| 78 |
+} |
|
| 0 | 79 |
\ No newline at end of file |
| 1 | 80 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,41 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.navigation |
|
| 18 |
+ |
|
| 19 |
+import kotlinx.serialization.Serializable |
|
| 20 |
+ |
|
| 21 |
+/** |
|
| 22 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:40 |
|
| 23 |
+ */ |
|
| 24 |
+ |
|
| 25 |
+@Serializable |
|
| 26 |
+data object Home |
|
| 27 |
+ |
|
| 28 |
+@Serializable |
|
| 29 |
+data object OnBoarding |
|
| 30 |
+ |
|
| 31 |
+@Serializable |
|
| 32 |
+data class EditNote(val noteId: String) |
|
| 33 |
+ |
|
| 34 |
+@Serializable |
|
| 35 |
+data object AddNote |
|
| 36 |
+ |
|
| 37 |
+@Serializable |
|
| 38 |
+data object Settings |
|
| 39 |
+ |
|
| 40 |
+@Serializable |
|
| 41 |
+data object About |
|
| 0 | 42 |
\ No newline at end of file |
| 1 | 43 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,43 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.navigation |
|
| 18 |
+ |
|
| 19 |
+import androidx.navigation.* |
|
| 20 |
+ |
|
| 21 |
+/** |
|
| 22 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:50 |
|
| 23 |
+ */ |
|
| 24 |
+ |
|
| 25 |
+fun NavHostController.goToEditNote(noteId: String) {
|
|
| 26 |
+ navigate(EditNote(noteId = noteId)) |
|
| 27 |
+} |
|
| 28 |
+ |
|
| 29 |
+fun NavHostController.goToAddNote() {
|
|
| 30 |
+ navigate(AddNote) |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+fun NavHostController.goToSettings(){
|
|
| 34 |
+ navigate(Settings) |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+fun NavHostController.goToHome(){
|
|
| 38 |
+ navigate(Home) |
|
| 39 |
+} |
|
| 40 |
+ |
|
| 41 |
+fun NavHostController.goToAbout(){
|
|
| 42 |
+ navigate(About) |
|
| 43 |
+} |
|
| 0 | 44 |
\ No newline at end of file |
| 1 | 45 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,32 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.navigation.nav_graph |
|
| 18 |
+ |
|
| 19 |
+import androidx.navigation.* |
|
| 20 |
+import androidx.navigation.compose.* |
|
| 21 |
+import com.certified.audionote.features.settings.* |
|
| 22 |
+import com.certified.audionote.navigation.* |
|
| 23 |
+ |
|
| 24 |
+/** |
|
| 25 |
+ * Created by MJ Jacobs on 2024/12/28 at 15:57 |
|
| 26 |
+ */ |
|
| 27 |
+ |
|
| 28 |
+fun NavGraphBuilder.settings(navController: NavHostController){
|
|
| 29 |
+ composable<Settings> {
|
|
| 30 |
+ SettingsScreen() |
|
| 31 |
+ } |
|
| 32 |
+} |
|
| 0 | 33 |
\ No newline at end of file |
| 1 | 34 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,43 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.navigation.nav_hosts |
|
| 18 |
+ |
|
| 19 |
+import androidx.compose.foundation.layout.* |
|
| 20 |
+import androidx.compose.runtime.* |
|
| 21 |
+import androidx.compose.ui.* |
|
| 22 |
+import androidx.navigation.* |
|
| 23 |
+import androidx.navigation.compose.* |
|
| 24 |
+import com.certified.audionote.navigation.* |
|
| 25 |
+import com.certified.audionote.navigation.nav_graph.* |
|
| 26 |
+ |
|
| 27 |
+/** |
|
| 28 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:56 |
|
| 29 |
+ */ |
|
| 30 |
+ |
|
| 31 |
+@Composable |
|
| 32 |
+fun CompactNavHost( |
|
| 33 |
+ navController: NavHostController |
|
| 34 |
+) {
|
|
| 35 |
+ |
|
| 36 |
+ NavHost( |
|
| 37 |
+ modifier = Modifier.fillMaxSize(), |
|
| 38 |
+ startDestination = Settings, |
|
| 39 |
+ navController = navController |
|
| 40 |
+ ) {
|
|
| 41 |
+ settings(navController = navController) |
|
| 42 |
+ } |
|
| 43 |
+} |
|
| 0 | 44 |
\ No newline at end of file |
| 1 | 45 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,31 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.navigation.nav_hosts |
|
| 18 |
+ |
|
| 19 |
+import androidx.compose.runtime.* |
|
| 20 |
+import androidx.navigation.* |
|
| 21 |
+ |
|
| 22 |
+/** |
|
| 23 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:56 |
|
| 24 |
+ */ |
|
| 25 |
+ |
|
| 26 |
+@Composable |
|
| 27 |
+fun ExpandedNavHost( |
|
| 28 |
+ navController: NavHostController |
|
| 29 |
+) {
|
|
| 30 |
+ |
|
| 31 |
+} |
|
| 0 | 32 |
\ No newline at end of file |
| 1 | 33 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,30 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.navigation.nav_hosts |
|
| 18 |
+ |
|
| 19 |
+import androidx.compose.runtime.* |
|
| 20 |
+import androidx.navigation.* |
|
| 21 |
+ |
|
| 22 |
+/** |
|
| 23 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:56 |
|
| 24 |
+ */ |
|
| 25 |
+ |
|
| 26 |
+@Composable |
|
| 27 |
+fun MediumNavHost( |
|
| 28 |
+ navController: NavHostController |
|
| 29 |
+) {
|
|
| 30 |
+} |
|
| 0 | 31 |
\ No newline at end of file |
| 1 | 32 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,36 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.repository |
|
| 18 |
+ |
|
| 19 |
+import com.certified.audionote.database.AudioNotesDAO |
|
| 20 |
+import com.certified.audionote.model.Note |
|
| 21 |
+import kotlinx.coroutines.flow.Flow |
|
| 22 |
+import javax.inject.Inject |
|
| 23 |
+import javax.inject.Singleton |
|
| 24 |
+ |
|
| 25 |
+@Singleton |
|
| 26 |
+class Repository @Inject constructor(private val audioNotesDAO: AudioNotesDAO) {
|
|
| 27 |
+ |
|
| 28 |
+ val allNotes: Flow<List<Note>?> = audioNotesDAO.getAllNotes() |
|
| 29 |
+ suspend fun insertNote(note: Note) = audioNotesDAO.insertNote(note) |
|
| 30 |
+ |
|
| 31 |
+ suspend fun updateNote(note: Note) = audioNotesDAO.updateNote(note) |
|
| 32 |
+ |
|
| 33 |
+ suspend fun deleteNote(note: Note) = audioNotesDAO.deleteNote(note) |
|
| 34 |
+ |
|
| 35 |
+ fun getNote(noteId: Int): Flow<Note> = audioNotesDAO.getNote(noteId) |
|
| 36 |
+} |
|
| 0 | 37 |
\ No newline at end of file |
| 1 | 38 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,56 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui |
|
| 18 |
+ |
|
| 19 |
+import android.os.Bundle |
|
| 20 |
+import android.view.LayoutInflater |
|
| 21 |
+import android.view.View |
|
| 22 |
+import android.view.ViewGroup |
|
| 23 |
+import androidx.fragment.app.Fragment |
|
| 24 |
+import androidx.navigation.NavController |
|
| 25 |
+import androidx.navigation.Navigation |
|
| 26 |
+import com.certified.audionote.databinding.FragmentAboutBinding |
|
| 27 |
+import com.certified.audionote.utils.Extensions.safeNavigate |
|
| 28 |
+ |
|
| 29 |
+class AboutFragment : Fragment() {
|
|
| 30 |
+ |
|
| 31 |
+ private var _binding: FragmentAboutBinding? = null |
|
| 32 |
+ private val binding get() = _binding!! |
|
| 33 |
+ private lateinit var navController: NavController |
|
| 34 |
+ |
|
| 35 |
+ override fun onCreateView( |
|
| 36 |
+ inflater: LayoutInflater, container: ViewGroup?, |
|
| 37 |
+ savedInstanceState: Bundle? |
|
| 38 |
+ ): View {
|
|
| 39 |
+ // Inflate the layout for this fragment |
|
| 40 |
+ _binding = FragmentAboutBinding.inflate(layoutInflater, container, false) |
|
| 41 |
+ return binding.root |
|
| 42 |
+ } |
|
| 43 |
+ |
|
| 44 |
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
| 45 |
+ super.onViewCreated(view, savedInstanceState) |
|
| 46 |
+ |
|
| 47 |
+ navController = Navigation.findNavController(view) |
|
| 48 |
+ |
|
| 49 |
+ binding.btnBack.setOnClickListener { navController.safeNavigate(AboutFragmentDirections.actionAboutFragmentToSettingsFragment()) }
|
|
| 50 |
+ } |
|
| 51 |
+ |
|
| 52 |
+ override fun onDestroyView() {
|
|
| 53 |
+ super.onDestroyView() |
|
| 54 |
+ _binding = null |
|
| 55 |
+ } |
|
| 56 |
+} |
|
| 0 | 57 |
\ No newline at end of file |
| 1 | 58 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,342 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui |
|
| 18 |
+ |
|
| 19 |
+import android.Manifest |
|
| 20 |
+import android.app.DatePickerDialog |
|
| 21 |
+import android.app.TimePickerDialog |
|
| 22 |
+import android.content.pm.PackageManager |
|
| 23 |
+import android.media.MediaRecorder |
|
| 24 |
+import android.os.Bundle |
|
| 25 |
+import android.view.LayoutInflater |
|
| 26 |
+import android.view.View |
|
| 27 |
+import android.view.ViewGroup |
|
| 28 |
+import android.view.WindowManager |
|
| 29 |
+import android.widget.DatePicker |
|
| 30 |
+import android.widget.TimePicker |
|
| 31 |
+import androidx.activity.result.contract.ActivityResultContracts |
|
| 32 |
+import androidx.core.content.ContextCompat |
|
| 33 |
+import androidx.core.content.res.ResourcesCompat |
|
| 34 |
+import androidx.fragment.app.Fragment |
|
| 35 |
+import androidx.fragment.app.viewModels |
|
| 36 |
+import androidx.navigation.NavController |
|
| 37 |
+import androidx.navigation.Navigation |
|
| 38 |
+import androidx.navigation.fragment.navArgs |
|
| 39 |
+import com.certified.audionote.R |
|
| 40 |
+import com.certified.audionote.databinding.DialogEditReminderBinding |
|
| 41 |
+import com.certified.audionote.databinding.FragmentAddNoteBinding |
|
| 42 |
+import com.certified.audionote.model.Note |
|
| 43 |
+import com.certified.audionote.utils.Extensions.safeNavigate |
|
| 44 |
+import com.certified.audionote.utils.Extensions.showKeyboardFor |
|
| 45 |
+import com.certified.audionote.utils.Extensions.showToast |
|
| 46 |
+import com.certified.audionote.utils.ReminderAvailableState |
|
| 47 |
+import com.certified.audionote.utils.cancelAlarm |
|
| 48 |
+import com.certified.audionote.utils.currentDate |
|
| 49 |
+import com.certified.audionote.utils.filePath |
|
| 50 |
+import com.certified.audionote.utils.formatReminderDate |
|
| 51 |
+import com.certified.audionote.utils.roundOffDecimal |
|
| 52 |
+import com.certified.audionote.utils.startAlarm |
|
| 53 |
+import com.google.android.material.bottomsheet.BottomSheetDialog |
|
| 54 |
+import com.google.android.material.dialog.MaterialAlertDialogBuilder |
|
| 55 |
+import dagger.hilt.android.AndroidEntryPoint |
|
| 56 |
+import timerx.* |
|
| 57 |
+import java.io.File |
|
| 58 |
+import java.io.IOException |
|
| 59 |
+import java.util.Calendar |
|
| 60 |
+import java.util.concurrent.TimeUnit |
|
| 61 |
+ |
|
| 62 |
+@AndroidEntryPoint |
|
| 63 |
+class AddNoteFragment : Fragment(), DatePickerDialog.OnDateSetListener, |
|
| 64 |
+ TimePickerDialog.OnTimeSetListener {
|
|
| 65 |
+ |
|
| 66 |
+ private var _binding: FragmentAddNoteBinding? = null |
|
| 67 |
+ private val binding get() = _binding!! |
|
| 68 |
+ |
|
| 69 |
+ private val viewModel: NotesViewModel by viewModels() |
|
| 70 |
+ private lateinit var navController: NavController |
|
| 71 |
+ |
|
| 72 |
+ private val args: EditNoteFragmentArgs by navArgs() |
|
| 73 |
+ private lateinit var _note: Note |
|
| 74 |
+ private var isRecording = false |
|
| 75 |
+ private var pickedDateTime: Calendar? = null |
|
| 76 |
+ private val currentDateTime by lazy { currentDate() }
|
|
| 77 |
+ private var mediaRecorder: MediaRecorder? = null |
|
| 78 |
+ private var file: File? = null |
|
| 79 |
+ private var stopWatch: Stopwatch? = null |
|
| 80 |
+ private var timer: Timer? = null |
|
| 81 |
+ |
|
| 82 |
+ private val requestAudioRecordingPermissionLauncher = |
|
| 83 |
+ registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
|
|
| 84 |
+ if (!isGranted) MaterialAlertDialogBuilder(requireContext()).apply {
|
|
| 85 |
+ setTitle(getString(R.string.audio_record_permission)) |
|
| 86 |
+ setMessage(getString(R.string.permission_required)) |
|
| 87 |
+ setPositiveButton(getString(R.string.ok)) { dialog, _ -> dialog.dismiss() }
|
|
| 88 |
+ show() |
|
| 89 |
+ } |
|
| 90 |
+ else startRecording() |
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 93 |
+ override fun onCreateView( |
|
| 94 |
+ inflater: LayoutInflater, container: ViewGroup?, |
|
| 95 |
+ savedInstanceState: Bundle? |
|
| 96 |
+ ): View {
|
|
| 97 |
+ // Inflate the layout for this fragment |
|
| 98 |
+ _binding = FragmentAddNoteBinding.inflate(layoutInflater, container, false) |
|
| 99 |
+ return binding.root |
|
| 100 |
+ } |
|
| 101 |
+ |
|
| 102 |
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
| 103 |
+ super.onViewCreated(view, savedInstanceState) |
|
| 104 |
+ |
|
| 105 |
+ navController = Navigation.findNavController(view) |
|
| 106 |
+ |
|
| 107 |
+ binding.lifecycleOwner = viewLifecycleOwner |
|
| 108 |
+ binding.viewModel = viewModel |
|
| 109 |
+ args.note.let {
|
|
| 110 |
+ _note = it |
|
| 111 |
+ binding.note = it |
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 114 |
+ binding.btnBack.setOnClickListener {
|
|
| 115 |
+ if (binding.etNoteTitle.text.toString().isNotBlank()) |
|
| 116 |
+ saveNote() |
|
| 117 |
+ else |
|
| 118 |
+ try {
|
|
| 119 |
+ file?.delete() |
|
| 120 |
+ } catch (e: Exception) {
|
|
| 121 |
+ e.printStackTrace() |
|
| 122 |
+ } |
|
| 123 |
+ navController.safeNavigate(AddNoteFragmentDirections.actionAddNoteFragmentToHomeFragment()) |
|
| 124 |
+ } |
|
| 125 |
+ binding.cardAddReminder.setOnClickListener {
|
|
| 126 |
+ if (viewModel.reminderAvailableState.value == ReminderAvailableState.NO_REMINDER) |
|
| 127 |
+ pickDate() |
|
| 128 |
+ else |
|
| 129 |
+ openEditReminderDialog() |
|
| 130 |
+ } |
|
| 131 |
+ binding.btnRecord.setOnClickListener { recordAudio() }
|
|
| 132 |
+ binding.fabSaveNote.setOnClickListener {
|
|
| 133 |
+ if (binding.etNoteTitle.text.toString().isNotBlank()) |
|
| 134 |
+ saveNote() |
|
| 135 |
+ else {
|
|
| 136 |
+ showToast(requireContext().getString(R.string.title_required)) |
|
| 137 |
+ binding.etNoteTitle.requestFocus() |
|
| 138 |
+ } |
|
| 139 |
+ } |
|
| 140 |
+ } |
|
| 141 |
+ |
|
| 142 |
+ override fun onResume() {
|
|
| 143 |
+ super.onResume() |
|
| 144 |
+ binding.etNoteTitle.apply {
|
|
| 145 |
+ requestFocus() |
|
| 146 |
+ showKeyboardFor(requireContext()) |
|
| 147 |
+ } |
|
| 148 |
+ updateStatusBarColor(binding.note!!.color) |
|
| 149 |
+ } |
|
| 150 |
+ |
|
| 151 |
+ override fun onDestroyView() {
|
|
| 152 |
+ super.onDestroyView() |
|
| 153 |
+ mediaRecorder = null |
|
| 154 |
+ timer?.apply {
|
|
| 155 |
+ stop() |
|
| 156 |
+ reset() |
|
| 157 |
+ } |
|
| 158 |
+ timer = null |
|
| 159 |
+ stopWatch?.apply {
|
|
| 160 |
+ stop() |
|
| 161 |
+ reset() |
|
| 162 |
+ } |
|
| 163 |
+ stopWatch = null |
|
| 164 |
+ _binding = null |
|
| 165 |
+ } |
|
| 166 |
+ |
|
| 167 |
+ private fun recordAudio() {
|
|
| 168 |
+ binding.apply {
|
|
| 169 |
+ if (!isRecording) {
|
|
| 170 |
+ if (ContextCompat.checkSelfPermission( |
|
| 171 |
+ requireContext(), Manifest.permission.RECORD_AUDIO |
|
| 172 |
+ ) == PackageManager.PERMISSION_GRANTED |
|
| 173 |
+ ) {
|
|
| 174 |
+ btnRecord.setImageDrawable( |
|
| 175 |
+ ResourcesCompat.getDrawable( |
|
| 176 |
+ resources, |
|
| 177 |
+ R.drawable.ic_mic_recording, |
|
| 178 |
+ null |
|
| 179 |
+ ) |
|
| 180 |
+ ).run {
|
|
| 181 |
+ try {
|
|
| 182 |
+ file?.delete() |
|
| 183 |
+ } catch (e: Exception) {
|
|
| 184 |
+ e.printStackTrace() |
|
| 185 |
+ } |
|
| 186 |
+ isRecording = true |
|
| 187 |
+ startRecording() |
|
| 188 |
+ } |
|
| 189 |
+ } else if (shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO)) |
|
| 190 |
+ MaterialAlertDialogBuilder(requireContext()).apply {
|
|
| 191 |
+ setTitle(getString(R.string.audio_record_permission)) |
|
| 192 |
+ setMessage(getString(R.string.permission_required)) |
|
| 193 |
+ setPositiveButton(getString(R.string.ok)) { dialog, _ -> dialog.dismiss() }
|
|
| 194 |
+ show() |
|
| 195 |
+ } |
|
| 196 |
+ else requestAudioRecordingPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO) |
|
| 197 |
+ } else {
|
|
| 198 |
+ btnRecord.setImageDrawable( |
|
| 199 |
+ ResourcesCompat.getDrawable( |
|
| 200 |
+ resources, R.drawable.ic_mic_not_recording, null |
|
| 201 |
+ ) |
|
| 202 |
+ ) |
|
| 203 |
+ .run {
|
|
| 204 |
+ isRecording = false |
|
| 205 |
+ stopRecording() |
|
| 206 |
+ } |
|
| 207 |
+ } |
|
| 208 |
+ } |
|
| 209 |
+ } |
|
| 210 |
+ |
|
| 211 |
+ override fun onDateSet(p0: DatePicker?, p1: Int, p2: Int, p3: Int) {
|
|
| 212 |
+ pickedDateTime = currentDate() |
|
| 213 |
+ pickedDateTime!!.set(p1, p2, p3) |
|
| 214 |
+ val hourOfDay = currentDateTime.get(Calendar.HOUR_OF_DAY) |
|
| 215 |
+ val minuteOfDay = currentDateTime.get(Calendar.MINUTE) |
|
| 216 |
+ val timePickerDialog = |
|
| 217 |
+ TimePickerDialog(requireContext(), this, hourOfDay, minuteOfDay, false) |
|
| 218 |
+ timePickerDialog.setOnDismissListener {
|
|
| 219 |
+ viewModel._reminderAvailableState.value = ReminderAvailableState.HAS_REMINDER |
|
| 220 |
+ _note.reminder = pickedDateTime!!.timeInMillis |
|
| 221 |
+ binding.tvReminderDate.text = formatReminderDate(pickedDateTime!!.timeInMillis) |
|
| 222 |
+ } |
|
| 223 |
+ timePickerDialog.show() |
|
| 224 |
+ } |
|
| 225 |
+ |
|
| 226 |
+ override fun onTimeSet(p0: TimePicker?, p1: Int, p2: Int) {
|
|
| 227 |
+ pickedDateTime!!.set(Calendar.HOUR_OF_DAY, p1) |
|
| 228 |
+ pickedDateTime!!.set(Calendar.MINUTE, p2) |
|
| 229 |
+ if (pickedDateTime!!.timeInMillis <= currentDate().timeInMillis) {
|
|
| 230 |
+ pickedDateTime!!.run {
|
|
| 231 |
+ set(Calendar.DAY_OF_MONTH, currentDateTime.get(Calendar.DAY_OF_MONTH) + 1) |
|
| 232 |
+ set(Calendar.YEAR, currentDateTime.get(Calendar.YEAR)) |
|
| 233 |
+ set(Calendar.MONTH, currentDateTime.get(Calendar.MONTH)) |
|
| 234 |
+ } |
|
| 235 |
+ } |
|
| 236 |
+ } |
|
| 237 |
+ |
|
| 238 |
+ private fun pickDate() {
|
|
| 239 |
+ val startYear = currentDateTime.get(Calendar.YEAR) |
|
| 240 |
+ val startMonth = currentDateTime.get(Calendar.MONTH) |
|
| 241 |
+ val startDay = currentDateTime.get(Calendar.DAY_OF_MONTH) |
|
| 242 |
+ val datePickerDialog = |
|
| 243 |
+ DatePickerDialog(requireContext(), this, startYear, startMonth, startDay) |
|
| 244 |
+ datePickerDialog.show() |
|
| 245 |
+ } |
|
| 246 |
+ |
|
| 247 |
+ private fun openEditReminderDialog() {
|
|
| 248 |
+ val view = DialogEditReminderBinding.inflate(layoutInflater) |
|
| 249 |
+ val bottomSheetDialog = BottomSheetDialog(requireContext()) |
|
| 250 |
+ view.apply {
|
|
| 251 |
+ note = _note |
|
| 252 |
+ btnDeleteReminder.setOnClickListener {
|
|
| 253 |
+ viewModel._reminderAvailableState.value = ReminderAvailableState.NO_REMINDER |
|
| 254 |
+ _note.reminder = null |
|
| 255 |
+ bottomSheetDialog.dismiss() |
|
| 256 |
+ } |
|
| 257 |
+ btnModifyReminder.setOnClickListener {
|
|
| 258 |
+ bottomSheetDialog.dismiss() |
|
| 259 |
+ pickDate() |
|
| 260 |
+ } |
|
| 261 |
+ } |
|
| 262 |
+ bottomSheetDialog.edgeToEdgeEnabled |
|
| 263 |
+ bottomSheetDialog.setContentView(view.root) |
|
| 264 |
+ bottomSheetDialog.show() |
|
| 265 |
+ } |
|
| 266 |
+ |
|
| 267 |
+ private fun saveNote() {
|
|
| 268 |
+ binding.apply {
|
|
| 269 |
+ stopRecording() |
|
| 270 |
+ if (_note.audioLength <= 0) {
|
|
| 271 |
+ showToast(requireContext().getString(R.string.record_note_before_saving)) |
|
| 272 |
+ return |
|
| 273 |
+ } |
|
| 274 |
+ val note = _note.copy( |
|
| 275 |
+ title = etNoteTitle.text.toString().trim(), |
|
| 276 |
+ description = etNoteDescription.text.toString().trim() |
|
| 277 |
+ ) |
|
| 278 |
+ this@AddNoteFragment.viewModel.insertNote(note) |
|
| 279 |
+ showToast(requireContext().getString(R.string.note_saved)) |
|
| 280 |
+ if (pickedDateTime?.timeInMillis != null && pickedDateTime!!.timeInMillis <= currentDateTime.timeInMillis) |
|
| 281 |
+ startAlarm(requireContext(), pickedDateTime!!.timeInMillis, note) |
|
| 282 |
+ navController.safeNavigate(AddNoteFragmentDirections.actionAddNoteFragmentToHomeFragment()) |
|
| 283 |
+ } |
|
| 284 |
+ } |
|
| 285 |
+ |
|
| 286 |
+ private fun startRecording() {
|
|
| 287 |
+ val filePath = filePath(requireActivity()) |
|
| 288 |
+ val fileName = "${System.currentTimeMillis()}.3gp"
|
|
| 289 |
+ _note.filePath = "$filePath/$fileName" |
|
| 290 |
+ |
|
| 291 |
+ stopWatch = buildStopwatch {
|
|
| 292 |
+ startFormat("MM:SS")
|
|
| 293 |
+ onTick { millis: Long, time: CharSequence->
|
|
| 294 |
+ binding.tvTimer.text = time |
|
| 295 |
+ } |
|
| 296 |
+ changeFormatWhen(1, TimeUnit.HOURS, "HH:MM:SS") |
|
| 297 |
+ } |
|
| 298 |
+ |
|
| 299 |
+ |
|
| 300 |
+ mediaRecorder = MediaRecorder().apply {
|
|
| 301 |
+ setAudioSource(MediaRecorder.AudioSource.MIC) |
|
| 302 |
+ setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) |
|
| 303 |
+ setOutputFile("$filePath/$fileName")
|
|
| 304 |
+ setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) |
|
| 305 |
+ try {
|
|
| 306 |
+ prepare() |
|
| 307 |
+ start() |
|
| 308 |
+ stopWatch!!.start() |
|
| 309 |
+ file = File("$filePath/$fileName")
|
|
| 310 |
+ } catch (e: IOException) {
|
|
| 311 |
+ showToast(requireContext().getString(R.string.error_occurred)) |
|
| 312 |
+ } |
|
| 313 |
+ } |
|
| 314 |
+ } |
|
| 315 |
+ |
|
| 316 |
+ private fun stopRecording() {
|
|
| 317 |
+ mediaRecorder?.apply {
|
|
| 318 |
+ stop() |
|
| 319 |
+ release() |
|
| 320 |
+ } |
|
| 321 |
+ mediaRecorder = null |
|
| 322 |
+ stopWatch?.apply {
|
|
| 323 |
+ stop() |
|
| 324 |
+ _note.audioLength = stopWatch!!.currentTimeInMillis / 1000 |
|
| 325 |
+ reset() |
|
| 326 |
+ } |
|
| 327 |
+ stopWatch = null |
|
| 328 |
+ if (_note.audioLength <= 0) |
|
| 329 |
+ return |
|
| 330 |
+ file = File(_note.filePath) |
|
| 331 |
+ val fileByte = (file!!.readBytes().size.toDouble() / 1048576.00) |
|
| 332 |
+ val fileSize = roundOffDecimal(fileByte) |
|
| 333 |
+ _note.size = fileSize |
|
| 334 |
+ } |
|
| 335 |
+ |
|
| 336 |
+ private fun updateStatusBarColor(color: Int) {
|
|
| 337 |
+ val window = requireActivity().window |
|
| 338 |
+ window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) |
|
| 339 |
+// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) |
|
| 340 |
+ window.statusBarColor = color |
|
| 341 |
+ } |
|
| 342 |
+} |
|
| 0 | 343 |
\ No newline at end of file |
| 1 | 344 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,65 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui |
|
| 18 |
+ |
|
| 19 |
+import android.content.BroadcastReceiver |
|
| 20 |
+import android.content.Context |
|
| 21 |
+import android.content.Intent |
|
| 22 |
+import androidx.work.Data |
|
| 23 |
+import androidx.work.ExistingWorkPolicy |
|
| 24 |
+import androidx.work.OneTimeWorkRequestBuilder |
|
| 25 |
+import androidx.work.WorkManager |
|
| 26 |
+import com.certified.audionote.utils.NotificationWorker |
|
| 27 |
+import java.util.concurrent.TimeUnit |
|
| 28 |
+ |
|
| 29 |
+class AlertReceiver : BroadcastReceiver() {
|
|
| 30 |
+ override fun onReceive(context: Context, intent: Intent) {
|
|
| 31 |
+ |
|
| 32 |
+ val noteId = intent.getIntExtra("noteId", 0)
|
|
| 33 |
+ val noteTitle = intent.getStringExtra("noteTitle")
|
|
| 34 |
+ val noteDescription = intent.getStringExtra("noteDescription")
|
|
| 35 |
+ val noteColor = intent.getIntExtra("noteColor", -1)
|
|
| 36 |
+ val noteLastModificationDate = intent.getLongExtra("noteLastModificationDate", -1L)
|
|
| 37 |
+ val noteSize = intent.getStringExtra("noteSize")
|
|
| 38 |
+ val noteAudioLength = intent.getLongExtra("noteAudioLength", 0L)
|
|
| 39 |
+ val noteFilePath = intent.getStringExtra("noteFilePath")
|
|
| 40 |
+ val noteStarted = intent.getBooleanExtra("noteStarted", false)
|
|
| 41 |
+ val noteReminder = intent.getLongExtra("noteReminder", -1L)
|
|
| 42 |
+ |
|
| 43 |
+ val data = Data.Builder() |
|
| 44 |
+ data.apply {
|
|
| 45 |
+ putInt("noteId", noteId)
|
|
| 46 |
+ putString("noteTitle", noteTitle)
|
|
| 47 |
+ putString("noteDescription", noteDescription)
|
|
| 48 |
+ putInt("noteColor", noteColor)
|
|
| 49 |
+ putLong("noteLastModificationDate", noteLastModificationDate)
|
|
| 50 |
+ putString("noteSize", noteSize)
|
|
| 51 |
+ putLong("noteAudioLength", noteAudioLength)
|
|
| 52 |
+ putString("noteFilePath", noteFilePath)
|
|
| 53 |
+ putBoolean("noteStarted", noteStarted)
|
|
| 54 |
+ putLong("noteReminder", noteReminder)
|
|
| 55 |
+ } |
|
| 56 |
+ val notificationRequest = OneTimeWorkRequestBuilder<NotificationWorker>() |
|
| 57 |
+ notificationRequest |
|
| 58 |
+ .setInitialDelay(10000, TimeUnit.MILLISECONDS).setInputData(data.build()) |
|
| 59 |
+ WorkManager.getInstance(context).beginUniqueWork( |
|
| 60 |
+ "Audio Notes notification work", |
|
| 61 |
+ ExistingWorkPolicy.REPLACE, |
|
| 62 |
+ notificationRequest.build() |
|
| 63 |
+ ).enqueue() |
|
| 64 |
+ } |
|
| 65 |
+} |
|
| 0 | 66 |
\ No newline at end of file |
| 1 | 67 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,383 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui |
|
| 18 |
+ |
|
| 19 |
+import android.app.DatePickerDialog |
|
| 20 |
+import android.app.TimePickerDialog |
|
| 21 |
+import android.content.Context |
|
| 22 |
+import android.content.Intent |
|
| 23 |
+import android.media.MediaPlayer |
|
| 24 |
+import android.os.Bundle |
|
| 25 |
+import android.util.Log |
|
| 26 |
+import android.view.LayoutInflater |
|
| 27 |
+import android.view.View |
|
| 28 |
+import android.view.ViewGroup |
|
| 29 |
+import android.view.WindowManager |
|
| 30 |
+import android.widget.DatePicker |
|
| 31 |
+import android.widget.TimePicker |
|
| 32 |
+import androidx.core.content.FileProvider |
|
| 33 |
+import androidx.core.content.res.ResourcesCompat |
|
| 34 |
+import androidx.fragment.app.Fragment |
|
| 35 |
+import androidx.fragment.app.viewModels |
|
| 36 |
+import androidx.lifecycle.lifecycleScope |
|
| 37 |
+import androidx.navigation.NavController |
|
| 38 |
+import androidx.navigation.Navigation |
|
| 39 |
+import androidx.navigation.fragment.navArgs |
|
| 40 |
+import com.certified.audionote.R |
|
| 41 |
+import com.certified.audionote.databinding.DialogEditReminderBinding |
|
| 42 |
+import com.certified.audionote.databinding.FragmentEditNoteBinding |
|
| 43 |
+import com.certified.audionote.model.Note |
|
| 44 |
+import com.certified.audionote.utils.Extensions.safeNavigate |
|
| 45 |
+import com.certified.audionote.utils.Extensions.showToast |
|
| 46 |
+import com.certified.audionote.utils.ReminderAvailableState |
|
| 47 |
+import com.certified.audionote.utils.ReminderCompletionState |
|
| 48 |
+import com.certified.audionote.utils.cancelAlarm |
|
| 49 |
+import com.certified.audionote.utils.currentDate |
|
| 50 |
+import com.certified.audionote.utils.formatReminderDate |
|
| 51 |
+import com.certified.audionote.utils.startAlarm |
|
| 52 |
+import com.google.android.material.bottomsheet.BottomSheetDialog |
|
| 53 |
+import com.google.android.material.dialog.MaterialAlertDialogBuilder |
|
| 54 |
+import dagger.hilt.android.AndroidEntryPoint |
|
| 55 |
+import kotlinx.coroutines.Dispatchers |
|
| 56 |
+import kotlinx.coroutines.launch |
|
| 57 |
+import timerx.* |
|
| 58 |
+import java.io.File |
|
| 59 |
+import java.io.IOException |
|
| 60 |
+import java.util.Calendar |
|
| 61 |
+import java.util.concurrent.TimeUnit |
|
| 62 |
+ |
|
| 63 |
+@AndroidEntryPoint |
|
| 64 |
+class EditNoteFragment : Fragment(), DatePickerDialog.OnDateSetListener, |
|
| 65 |
+ TimePickerDialog.OnTimeSetListener {
|
|
| 66 |
+ |
|
| 67 |
+ private var _binding: FragmentEditNoteBinding? = null |
|
| 68 |
+ private val binding get() = _binding!! |
|
| 69 |
+ |
|
| 70 |
+ private val viewModel: NotesViewModel by viewModels() |
|
| 71 |
+ private lateinit var navController: NavController |
|
| 72 |
+ |
|
| 73 |
+ private val args: EditNoteFragmentArgs by navArgs() |
|
| 74 |
+ private lateinit var _note: Note |
|
| 75 |
+ private var isPlayingRecord = false |
|
| 76 |
+ private var pickedDateTime: Calendar? = null |
|
| 77 |
+ private val currentDateTime by lazy { currentDate() }
|
|
| 78 |
+ private var mediaPlayer: MediaPlayer? = null |
|
| 79 |
+ private var file: File? = null |
|
| 80 |
+ private var stopWatch: Stopwatch? = null |
|
| 81 |
+ private var timer: Timer? = null |
|
| 82 |
+ |
|
| 83 |
+ override fun onCreateView( |
|
| 84 |
+ inflater: LayoutInflater, |
|
| 85 |
+ container: ViewGroup?, |
|
| 86 |
+ savedInstanceState: Bundle? |
|
| 87 |
+ ): View {
|
|
| 88 |
+ // Inflate the layout for this fragment |
|
| 89 |
+ _binding = FragmentEditNoteBinding.inflate(layoutInflater, container, false) |
|
| 90 |
+ return binding.root |
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 93 |
+ override fun onViewCreated( |
|
| 94 |
+ view: View, |
|
| 95 |
+ savedInstanceState: Bundle? |
|
| 96 |
+ ) {
|
|
| 97 |
+ super.onViewCreated(view, savedInstanceState) |
|
| 98 |
+ |
|
| 99 |
+ navController = Navigation.findNavController(view) |
|
| 100 |
+ |
|
| 101 |
+ binding.lifecycleOwner = viewLifecycleOwner |
|
| 102 |
+ binding.viewModel = viewModel |
|
| 103 |
+ args.note.let {
|
|
| 104 |
+ _note = it |
|
| 105 |
+ binding.note = it |
|
| 106 |
+ } |
|
| 107 |
+ |
|
| 108 |
+ binding.btnBack.setOnClickListener {
|
|
| 109 |
+ navController.safeNavigate(EditNoteFragmentDirections.actionEditNoteFragmentToHomeFragment()) |
|
| 110 |
+ } |
|
| 111 |
+ binding.cardAddReminder.setOnClickListener {
|
|
| 112 |
+ if (viewModel.reminderAvailableState.value == ReminderAvailableState.NO_REMINDER) |
|
| 113 |
+ pickDate() |
|
| 114 |
+ else |
|
| 115 |
+ openEditReminderDialog() |
|
| 116 |
+ } |
|
| 117 |
+ binding.btnShare.setOnClickListener { shareNote() }
|
|
| 118 |
+ binding.btnDelete.setOnClickListener { launchDeleteNoteDialog(requireContext()) }
|
|
| 119 |
+ binding.btnRecord.setOnClickListener { playPauseRecord() }
|
|
| 120 |
+ binding.fabUpdateNote.setOnClickListener { updateNote() }
|
|
| 121 |
+ |
|
| 122 |
+ setup() |
|
| 123 |
+ } |
|
| 124 |
+ |
|
| 125 |
+ private fun setup() {
|
|
| 126 |
+ lifecycleScope.launch {
|
|
| 127 |
+ file = File(_note.filePath) |
|
| 128 |
+ Log.d("TAG", "onViewCreated: ${file!!.name}")
|
|
| 129 |
+ } |
|
| 130 |
+ viewModel.apply {
|
|
| 131 |
+ if (_note.reminder != null) {
|
|
| 132 |
+ _reminderAvailableState.value = ReminderAvailableState.HAS_REMINDER |
|
| 133 |
+ if (currentDate().timeInMillis > args.note.reminder!!) {
|
|
| 134 |
+ _reminderCompletionState.value = ReminderCompletionState.COMPLETED |
|
| 135 |
+ } else {
|
|
| 136 |
+ _reminderCompletionState.value = ReminderCompletionState.ONGOING |
|
| 137 |
+ } |
|
| 138 |
+ } |
|
| 139 |
+ } |
|
| 140 |
+ } |
|
| 141 |
+ |
|
| 142 |
+ override fun onResume() {
|
|
| 143 |
+ super.onResume() |
|
| 144 |
+ updateStatusBarColor(args.note.color) |
|
| 145 |
+ } |
|
| 146 |
+ |
|
| 147 |
+ override fun onDestroyView() {
|
|
| 148 |
+ super.onDestroyView() |
|
| 149 |
+ if (isPlayingRecord) |
|
| 150 |
+ mediaPlayer?.apply {
|
|
| 151 |
+ stop() |
|
| 152 |
+ release() |
|
| 153 |
+ } |
|
| 154 |
+ mediaPlayer = null |
|
| 155 |
+ timer?.apply {
|
|
| 156 |
+ stop() |
|
| 157 |
+ reset() |
|
| 158 |
+ } |
|
| 159 |
+ timer = null |
|
| 160 |
+ stopWatch?.apply {
|
|
| 161 |
+ stop() |
|
| 162 |
+ reset() |
|
| 163 |
+ } |
|
| 164 |
+ stopWatch = null |
|
| 165 |
+ _binding = null |
|
| 166 |
+ } |
|
| 167 |
+ |
|
| 168 |
+ private fun playPauseRecord() {
|
|
| 169 |
+ binding.apply {
|
|
| 170 |
+ if (!isPlayingRecord) |
|
| 171 |
+ btnRecord.setImageDrawable( |
|
| 172 |
+ ResourcesCompat.getDrawable( |
|
| 173 |
+ resources, |
|
| 174 |
+ R.drawable.ic_audio_playing, null |
|
| 175 |
+ ) |
|
| 176 |
+ ) |
|
| 177 |
+ .run {
|
|
| 178 |
+ if (timer == null) |
|
| 179 |
+ startPlayingRecording() |
|
| 180 |
+ else |
|
| 181 |
+ continuePlayingRecording() |
|
| 182 |
+ isPlayingRecord = true |
|
| 183 |
+ } |
|
| 184 |
+ else |
|
| 185 |
+ btnRecord.setImageDrawable( |
|
| 186 |
+ ResourcesCompat.getDrawable( |
|
| 187 |
+ resources, |
|
| 188 |
+ R.drawable.ic_audio_not_playing, null |
|
| 189 |
+ ) |
|
| 190 |
+ ) |
|
| 191 |
+ .run {
|
|
| 192 |
+ if ((timer?.remainingTimeInMillis?.div(1000)) != 0L) |
|
| 193 |
+ pausePlayingRecording() |
|
| 194 |
+ else |
|
| 195 |
+ stopPlayingRecording() |
|
| 196 |
+ isPlayingRecord = false |
|
| 197 |
+ } |
|
| 198 |
+ } |
|
| 199 |
+ } |
|
| 200 |
+ |
|
| 201 |
+ private fun updateNote() {
|
|
| 202 |
+ val note = _note.copy( |
|
| 203 |
+ title = binding.etNoteTitle.text.toString().trim(), |
|
| 204 |
+ description = binding.etNoteDescription.text.toString().trim(), |
|
| 205 |
+ lastModificationDate = currentDate().timeInMillis |
|
| 206 |
+ ) |
|
| 207 |
+ if (note.title.isNotBlank()) {
|
|
| 208 |
+ viewModel.updateNote(note) |
|
| 209 |
+ if (pickedDateTime?.timeInMillis != null && pickedDateTime?.timeInMillis != currentDateTime.timeInMillis) |
|
| 210 |
+ startAlarm(requireContext(), pickedDateTime!!.timeInMillis, note) |
|
| 211 |
+ navController.safeNavigate(EditNoteFragmentDirections.actionEditNoteFragmentToHomeFragment()) |
|
| 212 |
+ } else {
|
|
| 213 |
+ showToast(requireContext().getString(R.string.title_required)) |
|
| 214 |
+ binding.etNoteTitle.requestFocus() |
|
| 215 |
+ } |
|
| 216 |
+ } |
|
| 217 |
+ |
|
| 218 |
+ override fun onDateSet( |
|
| 219 |
+ p0: DatePicker?, |
|
| 220 |
+ p1: Int, |
|
| 221 |
+ p2: Int, |
|
| 222 |
+ p3: Int |
|
| 223 |
+ ) {
|
|
| 224 |
+ pickedDateTime = currentDate() |
|
| 225 |
+ pickedDateTime!!.set(p1, p2, p3) |
|
| 226 |
+ val hourOfDay = currentDateTime.get(Calendar.HOUR_OF_DAY) |
|
| 227 |
+ val minuteOfDay = currentDateTime.get(Calendar.MINUTE) |
|
| 228 |
+ val timePickerDialog = |
|
| 229 |
+ TimePickerDialog(requireContext(), this, hourOfDay, minuteOfDay, false) |
|
| 230 |
+ timePickerDialog.setOnDismissListener {
|
|
| 231 |
+ viewModel._reminderAvailableState.value = ReminderAvailableState.HAS_REMINDER |
|
| 232 |
+ viewModel._reminderCompletionState.value = ReminderCompletionState.ONGOING |
|
| 233 |
+ _note.reminder = pickedDateTime!!.timeInMillis |
|
| 234 |
+ binding.tvReminderDate.text = formatReminderDate(pickedDateTime!!.timeInMillis) |
|
| 235 |
+ } |
|
| 236 |
+ timePickerDialog.show() |
|
| 237 |
+ } |
|
| 238 |
+ |
|
| 239 |
+ override fun onTimeSet( |
|
| 240 |
+ p0: TimePicker?, |
|
| 241 |
+ p1: Int, |
|
| 242 |
+ p2: Int |
|
| 243 |
+ ) {
|
|
| 244 |
+ pickedDateTime!!.set(Calendar.HOUR_OF_DAY, p1) |
|
| 245 |
+ pickedDateTime!!.set(Calendar.MINUTE, p2) |
|
| 246 |
+ if (pickedDateTime!!.timeInMillis <= currentDate().timeInMillis) {
|
|
| 247 |
+ pickedDateTime!!.run {
|
|
| 248 |
+ set(Calendar.DAY_OF_MONTH, currentDateTime.get(Calendar.DAY_OF_MONTH) + 1) |
|
| 249 |
+ set(Calendar.YEAR, currentDateTime.get(Calendar.YEAR)) |
|
| 250 |
+ set(Calendar.MONTH, currentDateTime.get(Calendar.MONTH)) |
|
| 251 |
+ } |
|
| 252 |
+ } |
|
| 253 |
+ } |
|
| 254 |
+ |
|
| 255 |
+ private fun pickDate() {
|
|
| 256 |
+ val startYear = currentDateTime.get(Calendar.YEAR) |
|
| 257 |
+ val startMonth = currentDateTime.get(Calendar.MONTH) |
|
| 258 |
+ val startDay = currentDateTime.get(Calendar.DAY_OF_MONTH) |
|
| 259 |
+ val datePickerDialog = |
|
| 260 |
+ DatePickerDialog(requireContext(), this, startYear, startMonth, startDay) |
|
| 261 |
+ datePickerDialog.show() |
|
| 262 |
+ } |
|
| 263 |
+ |
|
| 264 |
+ private fun openEditReminderDialog() {
|
|
| 265 |
+ val view = DialogEditReminderBinding.inflate(layoutInflater) |
|
| 266 |
+ val bottomSheetDialog = BottomSheetDialog(requireContext()) |
|
| 267 |
+ view.apply {
|
|
| 268 |
+ note = _note |
|
| 269 |
+ btnDeleteReminder.setOnClickListener {
|
|
| 270 |
+ viewModel._reminderAvailableState.value = ReminderAvailableState.NO_REMINDER |
|
| 271 |
+ _note.reminder = null |
|
| 272 |
+ cancelAlarm(requireContext(), _note.id) |
|
| 273 |
+ bottomSheetDialog.dismiss() |
|
| 274 |
+ } |
|
| 275 |
+ btnModifyReminder.setOnClickListener {
|
|
| 276 |
+ bottomSheetDialog.dismiss() |
|
| 277 |
+ pickDate() |
|
| 278 |
+ } |
|
| 279 |
+ } |
|
| 280 |
+ bottomSheetDialog.edgeToEdgeEnabled |
|
| 281 |
+ bottomSheetDialog.setContentView(view.root) |
|
| 282 |
+ bottomSheetDialog.show() |
|
| 283 |
+ } |
|
| 284 |
+ |
|
| 285 |
+ private fun launchDeleteNoteDialog(context: Context) {
|
|
| 286 |
+ val materialDialog = MaterialAlertDialogBuilder(context) |
|
| 287 |
+ materialDialog.apply {
|
|
| 288 |
+ setTitle(context.getString(R.string.delete_note)) |
|
| 289 |
+ setMessage("${context.getString(R.string.confirm_deletion)} ${_note.title}?")
|
|
| 290 |
+ setNegativeButton(context.getString(R.string.no)) { dialog, _ -> dialog?.dismiss() }
|
|
| 291 |
+ setPositiveButton(context.getString(R.string.yes)) { _, _ ->
|
|
| 292 |
+ viewModel.deleteNote(_note) |
|
| 293 |
+ lifecycleScope.launch(Dispatchers.IO) { file?.delete() }
|
|
| 294 |
+ navController.safeNavigate(EditNoteFragmentDirections.actionEditNoteFragmentToHomeFragment()) |
|
| 295 |
+ } |
|
| 296 |
+ show() |
|
| 297 |
+ } |
|
| 298 |
+ } |
|
| 299 |
+ |
|
| 300 |
+ private fun startPlayingRecording() {
|
|
| 301 |
+ timer = buildTimer {
|
|
| 302 |
+ startTime(_note.audioLength, TimeUnit.SECONDS) |
|
| 303 |
+ startFormat(if (_note.audioLength >= 3600000L) "HH:MM:SS" else "MM:SS") |
|
| 304 |
+ onTick { millis, time -> binding.tvTimer.text = time }
|
|
| 305 |
+ actionWhen(0, TimeUnit.SECONDS) {
|
|
| 306 |
+ binding.btnRecord.setImageDrawable( |
|
| 307 |
+ ResourcesCompat.getDrawable( |
|
| 308 |
+ resources, |
|
| 309 |
+ R.drawable.ic_audio_not_playing, |
|
| 310 |
+ null |
|
| 311 |
+ ) |
|
| 312 |
+ ).run {
|
|
| 313 |
+ isPlayingRecord = false |
|
| 314 |
+ stopPlayingRecording() |
|
| 315 |
+ } |
|
| 316 |
+ } |
|
| 317 |
+ } |
|
| 318 |
+ mediaPlayer = MediaPlayer() |
|
| 319 |
+ try {
|
|
| 320 |
+ mediaPlayer?.apply {
|
|
| 321 |
+ setDataSource(file?.absolutePath) |
|
| 322 |
+ prepare() |
|
| 323 |
+ start() |
|
| 324 |
+ } |
|
| 325 |
+ timer!!.start() |
|
| 326 |
+ } catch (e: IOException) {
|
|
| 327 |
+ e.printStackTrace() |
|
| 328 |
+ Log.d("TAG", "startPlayingRecording: ${e.localizedMessage}")
|
|
| 329 |
+ showToast(requireContext().getString(R.string.error_occurred)) |
|
| 330 |
+ } |
|
| 331 |
+ } |
|
| 332 |
+ |
|
| 333 |
+ private fun pausePlayingRecording() {
|
|
| 334 |
+ mediaPlayer?.pause() |
|
| 335 |
+ timer?.stop() |
|
| 336 |
+ } |
|
| 337 |
+ |
|
| 338 |
+ private fun continuePlayingRecording() {
|
|
| 339 |
+ mediaPlayer?.start() |
|
| 340 |
+ timer?.start() |
|
| 341 |
+ } |
|
| 342 |
+ |
|
| 343 |
+ private fun stopPlayingRecording() {
|
|
| 344 |
+ mediaPlayer?.apply {
|
|
| 345 |
+ stop() |
|
| 346 |
+ release() |
|
| 347 |
+ } |
|
| 348 |
+ timer?.apply {
|
|
| 349 |
+ reset() |
|
| 350 |
+ stop() |
|
| 351 |
+ } |
|
| 352 |
+ timer = null |
|
| 353 |
+ } |
|
| 354 |
+ |
|
| 355 |
+ private fun shareNote() {
|
|
| 356 |
+ if (file == null) {
|
|
| 357 |
+ showToast(requireContext().getString(R.string.file_not_found)) |
|
| 358 |
+ return |
|
| 359 |
+ } |
|
| 360 |
+ try {
|
|
| 361 |
+ val uri = FileProvider.getUriForFile( |
|
| 362 |
+ requireContext(), |
|
| 363 |
+ "com.certified.audionote.provider", |
|
| 364 |
+ file!! |
|
| 365 |
+ ) |
|
| 366 |
+ Intent(Intent.ACTION_SEND).apply {
|
|
| 367 |
+ type = "*/*" |
|
| 368 |
+ putExtra(Intent.EXTRA_STREAM, uri) |
|
| 369 |
+ startActivity(Intent.createChooser(this, "Share using")) |
|
| 370 |
+ } |
|
| 371 |
+ } catch (t: Throwable) {
|
|
| 372 |
+ showToast(requireContext().getString(R.string.error_occurred)) |
|
| 373 |
+ Log.d("TAG", "shareNote: ${t.localizedMessage}")
|
|
| 374 |
+ } |
|
| 375 |
+ } |
|
| 376 |
+ |
|
| 377 |
+ private fun updateStatusBarColor(color: Int) {
|
|
| 378 |
+ val window = requireActivity().window |
|
| 379 |
+ window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) |
|
| 380 |
+// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) |
|
| 381 |
+ window.statusBarColor = color |
|
| 382 |
+ } |
|
| 383 |
+} |
|
| 0 | 384 |
\ No newline at end of file |
| 1 | 385 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,114 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui |
|
| 18 |
+ |
|
| 19 |
+import android.os.Bundle |
|
| 20 |
+import android.view.LayoutInflater |
|
| 21 |
+import android.view.View |
|
| 22 |
+import android.view.ViewGroup |
|
| 23 |
+import androidx.fragment.app.Fragment |
|
| 24 |
+import androidx.fragment.app.viewModels |
|
| 25 |
+import androidx.navigation.NavController |
|
| 26 |
+import androidx.navigation.Navigation |
|
| 27 |
+import androidx.recyclerview.widget.GridLayoutManager |
|
| 28 |
+import com.certified.audionote.R |
|
| 29 |
+import com.certified.audionote.adapter.NoteRecyclerAdapter |
|
| 30 |
+import com.certified.audionote.databinding.FragmentHomeBinding |
|
| 31 |
+import com.certified.audionote.model.Note |
|
| 32 |
+import com.certified.audionote.repository.Repository |
|
| 33 |
+import com.certified.audionote.utils.Extensions.flags |
|
| 34 |
+import com.certified.audionote.utils.Extensions.safeNavigate |
|
| 35 |
+import com.google.android.material.bottomsheet.BottomSheetBehavior |
|
| 36 |
+import dagger.hilt.android.AndroidEntryPoint |
|
| 37 |
+import javax.inject.Inject |
|
| 38 |
+ |
|
| 39 |
+@AndroidEntryPoint |
|
| 40 |
+class HomeFragment : Fragment() {
|
|
| 41 |
+ |
|
| 42 |
+ private var _binding: FragmentHomeBinding? = null |
|
| 43 |
+ private val binding get() = _binding!! |
|
| 44 |
+ |
|
| 45 |
+ @Inject |
|
| 46 |
+ lateinit var repository: Repository |
|
| 47 |
+ private val viewModel: NotesViewModel by viewModels() |
|
| 48 |
+ private lateinit var navController: NavController |
|
| 49 |
+ |
|
| 50 |
+ override fun onCreateView( |
|
| 51 |
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? |
|
| 52 |
+ ): View {
|
|
| 53 |
+ // Inflate the layout for this fragment |
|
| 54 |
+ _binding = FragmentHomeBinding.inflate(inflater, container, false) |
|
| 55 |
+ return binding.root |
|
| 56 |
+ } |
|
| 57 |
+ |
|
| 58 |
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
| 59 |
+ super.onViewCreated(view, savedInstanceState) |
|
| 60 |
+ navController = Navigation.findNavController(view) |
|
| 61 |
+ |
|
| 62 |
+ binding.viewModel = viewModel |
|
| 63 |
+ binding.lifecycleOwner = viewLifecycleOwner |
|
| 64 |
+ |
|
| 65 |
+ NoteRecyclerAdapter { note ->
|
|
| 66 |
+ val action = HomeFragmentDirections.actionHomeFragmentToEditNoteFragment(note) |
|
| 67 |
+ navController.safeNavigate(action) |
|
| 68 |
+ }.apply {
|
|
| 69 |
+ val layoutManager = GridLayoutManager(requireContext(), 2) |
|
| 70 |
+ binding.recyclerViewNotes.also {
|
|
| 71 |
+ it.layoutManager = layoutManager |
|
| 72 |
+ it.adapter = this |
|
| 73 |
+ } |
|
| 74 |
+ } |
|
| 75 |
+ |
|
| 76 |
+ binding.apply {
|
|
| 77 |
+ btnSettings.setOnClickListener { navController.safeNavigate(HomeFragmentDirections.actionHomeFragmentToSettingsFragment()) }
|
|
| 78 |
+ fabAddNote.setOnClickListener {
|
|
| 79 |
+ val action = |
|
| 80 |
+ HomeFragmentDirections.actionHomeFragmentToAddNoteFragment(Note(audioLength = 0L)) |
|
| 81 |
+ navController.safeNavigate(action) |
|
| 82 |
+ } |
|
| 83 |
+ |
|
| 84 |
+ val bottomSheetBehavior = |
|
| 85 |
+ BottomSheetBehavior.from(bottomSheetDialogLayout.bottomSheetDialog) |
|
| 86 |
+ bottomSheetBehavior.addBottomSheetCallback(object : |
|
| 87 |
+ BottomSheetBehavior.BottomSheetCallback() {
|
|
| 88 |
+ override fun onStateChanged(bottomSheet: View, newState: Int) {
|
|
| 89 |
+ if (newState == BottomSheetBehavior.STATE_HIDDEN) bottomSheetBehavior.state = |
|
| 90 |
+ BottomSheetBehavior.STATE_COLLAPSED |
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 93 |
+ override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
|
| 94 |
+// Unused |
|
| 95 |
+ } |
|
| 96 |
+ }) |
|
| 97 |
+ bottomSheetDialogLayout.linearLayoutCompat.setOnClickListener {
|
|
| 98 |
+ if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) bottomSheetBehavior.state = |
|
| 99 |
+ BottomSheetBehavior.STATE_EXPANDED |
|
| 100 |
+ else bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED |
|
| 101 |
+ } |
|
| 102 |
+ } |
|
| 103 |
+ } |
|
| 104 |
+ |
|
| 105 |
+ override fun onResume() {
|
|
| 106 |
+ super.onResume() |
|
| 107 |
+ flags(R.color.fragment_background) |
|
| 108 |
+ } |
|
| 109 |
+ |
|
| 110 |
+ override fun onDestroyView() {
|
|
| 111 |
+ super.onDestroyView() |
|
| 112 |
+ _binding = null |
|
| 113 |
+ } |
|
| 114 |
+} |
|
| 0 | 115 |
\ No newline at end of file |
| 1 | 116 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,92 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui |
|
| 18 |
+ |
|
| 19 |
+import androidx.lifecycle.ViewModel |
|
| 20 |
+import androidx.lifecycle.viewModelScope |
|
| 21 |
+import com.certified.audionote.model.Note |
|
| 22 |
+import com.certified.audionote.repository.Repository |
|
| 23 |
+import com.certified.audionote.utils.ReminderAvailableState |
|
| 24 |
+import com.certified.audionote.utils.ReminderCompletionState |
|
| 25 |
+import com.certified.audionote.utils.UIState |
|
| 26 |
+import dagger.hilt.android.lifecycle.HiltViewModel |
|
| 27 |
+import kotlinx.coroutines.Dispatchers |
|
| 28 |
+import kotlinx.coroutines.flow.MutableStateFlow |
|
| 29 |
+import kotlinx.coroutines.flow.asStateFlow |
|
| 30 |
+import kotlinx.coroutines.launch |
|
| 31 |
+import javax.inject.Inject |
|
| 32 |
+ |
|
| 33 |
+@HiltViewModel |
|
| 34 |
+class NotesViewModel @Inject constructor(private val repository: Repository) : ViewModel() {
|
|
| 35 |
+ |
|
| 36 |
+ val _reminderAvailableState = MutableStateFlow(ReminderAvailableState.NO_REMINDER) |
|
| 37 |
+ val reminderAvailableState = _reminderAvailableState.asStateFlow() |
|
| 38 |
+ |
|
| 39 |
+ val _reminderCompletionState = MutableStateFlow(ReminderCompletionState.ONGOING) |
|
| 40 |
+ val reminderCompletionState = _reminderCompletionState.asStateFlow() |
|
| 41 |
+ |
|
| 42 |
+ private val _uiState = MutableStateFlow(UIState.LOADING) |
|
| 43 |
+ val uiState = _uiState.asStateFlow() |
|
| 44 |
+ |
|
| 45 |
+ private val _notes = MutableStateFlow<List<Note>?>(null) |
|
| 46 |
+ val notes = _notes.asStateFlow() |
|
| 47 |
+ |
|
| 48 |
+ private val _note = MutableStateFlow<Note?>(null) |
|
| 49 |
+ val note = _note.asStateFlow() |
|
| 50 |
+ |
|
| 51 |
+ init {
|
|
| 52 |
+ getNotes() |
|
| 53 |
+ } |
|
| 54 |
+ |
|
| 55 |
+ private fun getNotes() {
|
|
| 56 |
+ viewModelScope.launch {
|
|
| 57 |
+ repository.allNotes.collect {
|
|
| 58 |
+ _notes.value = it |
|
| 59 |
+ if (it.isNullOrEmpty()) |
|
| 60 |
+ _uiState.value = UIState.EMPTY |
|
| 61 |
+ else |
|
| 62 |
+ _uiState.value = UIState.HAS_DATA |
|
| 63 |
+ } |
|
| 64 |
+ } |
|
| 65 |
+ } |
|
| 66 |
+ |
|
| 67 |
+ fun insertNote(note: Note) {
|
|
| 68 |
+ viewModelScope.launch(Dispatchers.IO) {
|
|
| 69 |
+ repository.insertNote(note) |
|
| 70 |
+ } |
|
| 71 |
+ } |
|
| 72 |
+ |
|
| 73 |
+ fun updateNote(note: Note) {
|
|
| 74 |
+ viewModelScope.launch(Dispatchers.IO) {
|
|
| 75 |
+ repository.updateNote(note) |
|
| 76 |
+ } |
|
| 77 |
+ } |
|
| 78 |
+ |
|
| 79 |
+ fun deleteNote(note: Note) {
|
|
| 80 |
+ viewModelScope.launch(Dispatchers.IO) {
|
|
| 81 |
+ repository.deleteNote(note) |
|
| 82 |
+ } |
|
| 83 |
+ } |
|
| 84 |
+ |
|
| 85 |
+ fun getNote(noteId: Int) {
|
|
| 86 |
+ viewModelScope.launch(Dispatchers.IO) {
|
|
| 87 |
+ repository.getNote(noteId).collect {
|
|
| 88 |
+ _note.value = it |
|
| 89 |
+ } |
|
| 90 |
+ } |
|
| 91 |
+ } |
|
| 92 |
+} |
|
| 0 | 93 |
\ No newline at end of file |
| 1 | 94 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,112 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui |
|
| 18 |
+ |
|
| 19 |
+import android.os.Bundle |
|
| 20 |
+import android.view.LayoutInflater |
|
| 21 |
+import android.view.View |
|
| 22 |
+import android.view.ViewGroup |
|
| 23 |
+import androidx.datastore.preferences.core.edit |
|
| 24 |
+import androidx.fragment.app.Fragment |
|
| 25 |
+import androidx.lifecycle.lifecycleScope |
|
| 26 |
+import androidx.navigation.fragment.findNavController |
|
| 27 |
+import androidx.viewpager2.widget.ViewPager2 |
|
| 28 |
+import com.certified.audionote.R |
|
| 29 |
+import com.certified.audionote.adapter.ViewPagerAdapter |
|
| 30 |
+import com.certified.audionote.databinding.FragmentOnboardingBinding |
|
| 31 |
+import com.certified.audionote.model.SliderItem |
|
| 32 |
+import com.certified.audionote.utils.Extensions.dataStore |
|
| 33 |
+import com.certified.audionote.utils.Extensions.safeNavigate |
|
| 34 |
+import com.certified.audionote.utils.PreferenceKeys |
|
| 35 |
+import kotlinx.coroutines.launch |
|
| 36 |
+ |
|
| 37 |
+class OnboardingFragment : Fragment() {
|
|
| 38 |
+ |
|
| 39 |
+ private var _binding: FragmentOnboardingBinding? = null |
|
| 40 |
+ private val binding get() = _binding!! |
|
| 41 |
+ private lateinit var sliderItem: ArrayList<SliderItem> |
|
| 42 |
+ |
|
| 43 |
+ override fun onCreateView( |
|
| 44 |
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? |
|
| 45 |
+ ): View {
|
|
| 46 |
+ // Inflate the layout for this fragment |
|
| 47 |
+ _binding = FragmentOnboardingBinding.inflate(layoutInflater, container, false) |
|
| 48 |
+ return binding.root |
|
| 49 |
+ } |
|
| 50 |
+ |
|
| 51 |
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
| 52 |
+ super.onViewCreated(view, savedInstanceState) |
|
| 53 |
+ |
|
| 54 |
+ setUpSliderItem() |
|
| 55 |
+ setUpViewPager() |
|
| 56 |
+ |
|
| 57 |
+ binding.btnGetStarted.setOnClickListener {
|
|
| 58 |
+ lifecycleScope.launch {
|
|
| 59 |
+ requireContext().dataStore.edit {
|
|
| 60 |
+ it[PreferenceKeys.FIRST_TIME_LOGIN] = false |
|
| 61 |
+ } |
|
| 62 |
+ findNavController().safeNavigate(OnboardingFragmentDirections.actionOnboardingFragmentToHomeFragment()) |
|
| 63 |
+ } |
|
| 64 |
+ } |
|
| 65 |
+ } |
|
| 66 |
+ |
|
| 67 |
+ override fun onDestroyView() {
|
|
| 68 |
+ super.onDestroyView() |
|
| 69 |
+ _binding = null |
|
| 70 |
+ } |
|
| 71 |
+ |
|
| 72 |
+ private fun setUpSliderItem() {
|
|
| 73 |
+ sliderItem = ArrayList() |
|
| 74 |
+ sliderItem.add( |
|
| 75 |
+ SliderItem( |
|
| 76 |
+ R.drawable.ic_undraw_empty, |
|
| 77 |
+ getString(R.string.view_pager_title_audio_recording), |
|
| 78 |
+ getString(R.string.view_pager_description_audio_recording) |
|
| 79 |
+ ) |
|
| 80 |
+ ) |
|
| 81 |
+ sliderItem.add( |
|
| 82 |
+ SliderItem( |
|
| 83 |
+ R.drawable.ic_undraw_empty, |
|
| 84 |
+ getString(R.string.view_pager_title_notification), |
|
| 85 |
+ getString(R.string.view_pager_description_notification) |
|
| 86 |
+ ) |
|
| 87 |
+ ) |
|
| 88 |
+ sliderItem.add( |
|
| 89 |
+ SliderItem( |
|
| 90 |
+ R.drawable.ic_undraw_empty, |
|
| 91 |
+ getString(R.string.view_pager_title_dark_mode), |
|
| 92 |
+ getString(R.string.view_pager_description_dark_mode) |
|
| 93 |
+ ) |
|
| 94 |
+ ) |
|
| 95 |
+ } |
|
| 96 |
+ |
|
| 97 |
+ private fun setUpViewPager() {
|
|
| 98 |
+ val viewPagerAdapter = ViewPagerAdapter() |
|
| 99 |
+ viewPagerAdapter.submitList(sliderItem) |
|
| 100 |
+ binding.viewPager.adapter = viewPagerAdapter |
|
| 101 |
+ binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
|
| 102 |
+ override fun onPageSelected(position: Int) {
|
|
| 103 |
+ super.onPageSelected(position) |
|
| 104 |
+ binding.indicator.selection = position |
|
| 105 |
+ if (position == sliderItem.size - 1) {
|
|
| 106 |
+ binding.indicator.count = sliderItem.size |
|
| 107 |
+ binding.indicator.selection = position |
|
| 108 |
+ } |
|
| 109 |
+ } |
|
| 110 |
+ }) |
|
| 111 |
+ } |
|
| 112 |
+} |
|
| 0 | 113 |
\ No newline at end of file |
| 1 | 114 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,62 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui |
|
| 18 |
+ |
|
| 19 |
+import android.content.SharedPreferences |
|
| 20 |
+import android.os.Bundle |
|
| 21 |
+import androidx.appcompat.app.AppCompatDelegate |
|
| 22 |
+import androidx.preference.PreferenceFragmentCompat |
|
| 23 |
+import androidx.preference.PreferenceManager |
|
| 24 |
+import com.certified.audionote.R |
|
| 25 |
+ |
|
| 26 |
+class PreferenceFragment : PreferenceFragmentCompat(), |
|
| 27 |
+ SharedPreferences.OnSharedPreferenceChangeListener {
|
|
| 28 |
+ |
|
| 29 |
+ override fun onCreate(savedInstanceState: Bundle?) {
|
|
| 30 |
+ super.onCreate(savedInstanceState) |
|
| 31 |
+ |
|
| 32 |
+ PreferenceManager.getDefaultSharedPreferences(requireContext()) |
|
| 33 |
+ .registerOnSharedPreferenceChangeListener(this) |
|
| 34 |
+ } |
|
| 35 |
+ |
|
| 36 |
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
| 37 |
+ setPreferencesFromResource(R.xml.root_preferences, rootKey) |
|
| 38 |
+ } |
|
| 39 |
+ |
|
| 40 |
+ override fun onSharedPreferenceChanged( |
|
| 41 |
+ sharedPreferences: SharedPreferences?, |
|
| 42 |
+ key: String? |
|
| 43 |
+ ) {
|
|
| 44 |
+ val darkModePreference = getString(R.string.key_theme) |
|
| 45 |
+ key?.let {
|
|
| 46 |
+ if (it == darkModePreference) sharedPreferences?.let { pref ->
|
|
| 47 |
+ val darkModeValues = resources.getStringArray(R.array.pref_theme_values) |
|
| 48 |
+ when (pref.getString(darkModePreference, darkModeValues[0])) {
|
|
| 49 |
+ darkModeValues[0] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) |
|
| 50 |
+ darkModeValues[1] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) |
|
| 51 |
+ darkModeValues[2] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) |
|
| 52 |
+ } |
|
| 53 |
+ } |
|
| 54 |
+ } |
|
| 55 |
+ } |
|
| 56 |
+ |
|
| 57 |
+ override fun onDestroyView() {
|
|
| 58 |
+ super.onDestroyView() |
|
| 59 |
+ PreferenceManager.getDefaultSharedPreferences(requireContext()) |
|
| 60 |
+ .unregisterOnSharedPreferenceChangeListener(this) |
|
| 61 |
+ } |
|
| 62 |
+} |
|
| 0 | 63 |
\ No newline at end of file |
| 1 | 64 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,138 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui.main |
|
| 18 |
+ |
|
| 19 |
+import android.Manifest |
|
| 20 |
+import android.app.* |
|
| 21 |
+import android.content.* |
|
| 22 |
+import android.content.pm.* |
|
| 23 |
+import android.media.* |
|
| 24 |
+import android.os.* |
|
| 25 |
+import androidx.activity.* |
|
| 26 |
+import androidx.activity.result.contract.* |
|
| 27 |
+import androidx.appcompat.app.* |
|
| 28 |
+import androidx.core.content.* |
|
| 29 |
+import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen |
|
| 30 |
+import androidx.lifecycle.* |
|
| 31 |
+import androidx.navigation.* |
|
| 32 |
+import androidx.navigation.fragment.* |
|
| 33 |
+import androidx.preference.* |
|
| 34 |
+import com.certified.audionote.R |
|
| 35 |
+import com.certified.audionote.databinding.* |
|
| 36 |
+import com.certified.audionote.utils.* |
|
| 37 |
+import com.certified.audionote.utils.Extensions.dataStore |
|
| 38 |
+import com.google.android.material.dialog.* |
|
| 39 |
+import dagger.hilt.android.* |
|
| 40 |
+import kotlinx.coroutines.* |
|
| 41 |
+import kotlinx.coroutines.flow.* |
|
| 42 |
+ |
|
| 43 |
+@AndroidEntryPoint |
|
| 44 |
+class MainActivity : AppCompatActivity() {
|
|
| 45 |
+ |
|
| 46 |
+ private var _binding: ActivityMainBinding? = null |
|
| 47 |
+ private val binding get() = _binding!! |
|
| 48 |
+ private val viewModel: MainViewModel by viewModels() |
|
| 49 |
+ private lateinit var navController: NavController |
|
| 50 |
+ |
|
| 51 |
+ private val requestNotificationPermissionLauncher = |
|
| 52 |
+ registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
|
|
| 53 |
+ if (!isGranted) MaterialAlertDialogBuilder(this).apply {
|
|
| 54 |
+ setTitle(getString(R.string.notification_permission)) |
|
| 55 |
+ setMessage(getString(R.string.notification_permission_required)) |
|
| 56 |
+ setPositiveButton(getString(R.string.ok)) { dialog, _ -> dialog.dismiss() }
|
|
| 57 |
+ show() |
|
| 58 |
+ } |
|
| 59 |
+ } |
|
| 60 |
+ |
|
| 61 |
+ override fun onCreate(savedInstanceState: Bundle?) {
|
|
| 62 |
+ super.onCreate(savedInstanceState) |
|
| 63 |
+ |
|
| 64 |
+ val splashScreen = installSplashScreen() |
|
| 65 |
+ _binding = ActivityMainBinding.inflate(layoutInflater) |
|
| 66 |
+ setContentView(binding.root) |
|
| 67 |
+ |
|
| 68 |
+ val navHostFragment = |
|
| 69 |
+ supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment |
|
| 70 |
+ navController = navHostFragment.navController |
|
| 71 |
+ |
|
| 72 |
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
| 73 |
+ val notificationManager = |
|
| 74 |
+ getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager |
|
| 75 |
+ val defaultSoundUri = |
|
| 76 |
+ RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) |
|
| 77 |
+ val audioAttributes = |
|
| 78 |
+ AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) |
|
| 79 |
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build() |
|
| 80 |
+ val channel = NotificationChannel( |
|
| 81 |
+ getString(R.string.channelId), |
|
| 82 |
+ getString(R.string.app_name), |
|
| 83 |
+ NotificationManager.IMPORTANCE_DEFAULT |
|
| 84 |
+ ) |
|
| 85 |
+ channel.enableVibration(true) |
|
| 86 |
+ channel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400) |
|
| 87 |
+ channel.setSound(defaultSoundUri, audioAttributes) |
|
| 88 |
+ notificationManager.createNotificationChannel(channel) |
|
| 89 |
+ } |
|
| 90 |
+ |
|
| 91 |
+ isDarkModeEnabled() |
|
| 92 |
+ checkNotificationPermission() |
|
| 93 |
+ splashScreen.setKeepOnScreenCondition { viewModel.isLoading.value }
|
|
| 94 |
+ lifecycleScope.launch(Dispatchers.Main) {
|
|
| 95 |
+ this@MainActivity.dataStore.data.map { it[PreferenceKeys.FIRST_TIME_LOGIN] }.collect {
|
|
| 96 |
+ if (it != null) navController.navigate(R.id.homeFragment) |
|
| 97 |
+ } |
|
| 98 |
+ } |
|
| 99 |
+ } |
|
| 100 |
+ |
|
| 101 |
+ private fun isDarkModeEnabled() {
|
|
| 102 |
+ val darkModePreference = getString(R.string.key_theme) |
|
| 103 |
+ val darkModeValues = resources.getStringArray(R.array.pref_theme_values) |
|
| 104 |
+ val preferences = PreferenceManager.getDefaultSharedPreferences(this) |
|
| 105 |
+ when (preferences.getString(darkModePreference, darkModeValues[0])) {
|
|
| 106 |
+ darkModeValues[0] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) |
|
| 107 |
+ darkModeValues[1] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) |
|
| 108 |
+ darkModeValues[2] -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) |
|
| 109 |
+ } |
|
| 110 |
+ } |
|
| 111 |
+ |
|
| 112 |
+ private fun checkNotificationPermission() {
|
|
| 113 |
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
| 114 |
+ if (ContextCompat.checkSelfPermission( |
|
| 115 |
+ this, Manifest.permission.POST_NOTIFICATIONS |
|
| 116 |
+ ) == PackageManager.PERMISSION_GRANTED |
|
| 117 |
+ ) {
|
|
| 118 |
+ // FCM SDK (and your app) can post notifications. |
|
| 119 |
+ } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) |
|
| 120 |
+ MaterialAlertDialogBuilder(this).apply {
|
|
| 121 |
+ setTitle(getString(R.string.notification_permission)) |
|
| 122 |
+ setMessage(getString(R.string.notification_permission_required)) |
|
| 123 |
+ setPositiveButton(getString(R.string.ok)) { dialog, _ -> dialog.dismiss() }
|
|
| 124 |
+ show() |
|
| 125 |
+ } |
|
| 126 |
+ else |
|
| 127 |
+ requestNotificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) |
|
| 128 |
+ } |
|
| 129 |
+ } |
|
| 130 |
+ |
|
| 131 |
+ private suspend fun isFirstLogin() {
|
|
| 132 |
+ } |
|
| 133 |
+ |
|
| 134 |
+ override fun onDestroy() {
|
|
| 135 |
+ super.onDestroy() |
|
| 136 |
+ _binding = null |
|
| 137 |
+ } |
|
| 138 |
+} |
|
| 0 | 139 |
\ No newline at end of file |
| 1 | 140 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,23 @@ |
| 1 |
+package com.certified.audionote.ui.main |
|
| 2 |
+ |
|
| 3 |
+import androidx.lifecycle.ViewModel |
|
| 4 |
+import androidx.lifecycle.viewModelScope |
|
| 5 |
+import dagger.hilt.android.lifecycle.HiltViewModel |
|
| 6 |
+import kotlinx.coroutines.delay |
|
| 7 |
+import kotlinx.coroutines.flow.MutableStateFlow |
|
| 8 |
+import kotlinx.coroutines.flow.asStateFlow |
|
| 9 |
+import kotlinx.coroutines.launch |
|
| 10 |
+ |
|
| 11 |
+//@HiltViewModel |
|
| 12 |
+class MainViewModel : ViewModel() {
|
|
| 13 |
+ |
|
| 14 |
+ private val _isLoading = MutableStateFlow(true) |
|
| 15 |
+ val isLoading = _isLoading.asStateFlow() |
|
| 16 |
+ |
|
| 17 |
+ init {
|
|
| 18 |
+ viewModelScope.launch {
|
|
| 19 |
+ delay(1000L) |
|
| 20 |
+ _isLoading.value = false |
|
| 21 |
+ } |
|
| 22 |
+ } |
|
| 23 |
+} |
|
| 0 | 24 |
\ No newline at end of file |
| 1 | 25 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,69 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui.theme |
|
| 18 |
+ |
|
| 19 |
+import androidx.compose.foundation.* |
|
| 20 |
+import androidx.compose.runtime.* |
|
| 21 |
+import androidx.compose.ui.graphics.* |
|
| 22 |
+ |
|
| 23 |
+/** |
|
| 24 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:07 |
|
| 25 |
+ */ |
|
| 26 |
+ |
|
| 27 |
+// Light colors |
|
| 28 |
+val purple200 = Color(0xFFBB86FC) |
|
| 29 |
+val purple500 = Color(0xFF6200EE) |
|
| 30 |
+val purple700 = Color(0xFF3700B3) |
|
| 31 |
+val teal200 = Color(0xFF03DAC5) |
|
| 32 |
+val teal700 = Color(0xFF018786) |
|
| 33 |
+val black = Color(0xFF000000) |
|
| 34 |
+val white = Color(0xFFFFFFFF) |
|
| 35 |
+ |
|
| 36 |
+val accentLight = Color(0xFFFFECF1) |
|
| 37 |
+val fragment_background = accentLight |
|
| 38 |
+val other_fragment_background = Color(0xFF986977) |
|
| 39 |
+val primaryLight = Color(0xFFEFB8C8) |
|
| 40 |
+val primaryDarkLight = Color(0xFFD29DAC) |
|
| 41 |
+val primaryDarkerLight = Color(0xFF986977) |
|
| 42 |
+val micAccentLight = Color(0xFF939094) |
|
| 43 |
+val fabBackgroundTintLight = primaryLight |
|
| 44 |
+val aboutIconColorLight = Color(0xFFEFB8C8) |
|
| 45 |
+val editReminderButtonColorLight = other_fragment_background |
|
| 46 |
+val greyLight = Color(0xFFAEAEAE) |
|
| 47 |
+val titleTextLight = primaryDarkerLight |
|
| 48 |
+val subtitleTextLight = primaryDarkLight |
|
| 49 |
+ |
|
| 50 |
+// Dark colors |
|
| 51 |
+val primaryDark = Color(0xFF313033) |
|
| 52 |
+val primaryDarkDark = Color(0xFF1C1B1F) |
|
| 53 |
+val primaryDarkerDark = black |
|
| 54 |
+val accentDark = white |
|
| 55 |
+val fragmentBackgroundDark = primaryDark |
|
| 56 |
+val otherFragmentBackgroundDark = primaryDarkerDark |
|
| 57 |
+val micAccentDark = Color(0xFF939094) |
|
| 58 |
+val fabBackgroundTintDark = Color(0xFFEFB8C8) |
|
| 59 |
+val aboutIconColorDark = Color(0xFF939094) |
|
| 60 |
+val editReminderButtonColorDark = aboutIconColorDark |
|
| 61 |
+val greyDark = white |
|
| 62 |
+val titleTextDark = white |
|
| 63 |
+val subtitleTextDark = white |
|
| 64 |
+ |
|
| 65 |
+@Composable |
|
| 66 |
+fun dayNightBackgroundColor(): Color = if (isSystemInDarkTheme()) black else white |
|
| 67 |
+ |
|
| 68 |
+@Composable |
|
| 69 |
+fun statusBarColor(): Color = if (isSystemInDarkTheme()) primaryDarkDark else primaryDarkLight |
|
| 0 | 70 |
\ No newline at end of file |
| 1 | 71 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,30 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui.theme |
|
| 18 |
+ |
|
| 19 |
+import androidx.compose.ui.unit.* |
|
| 20 |
+ |
|
| 21 |
+/** |
|
| 22 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:28 |
|
| 23 |
+ */ |
|
| 24 |
+ |
|
| 25 |
+val largePadding = 32.dp |
|
| 26 |
+val normalPadding = 16.dp |
|
| 27 |
+val halfPadding = 8.dp |
|
| 28 |
+val smallPadding = 4.dp |
|
| 29 |
+ |
|
| 30 |
+val defaultCornerSize = 15.dp |
|
| 0 | 31 |
\ No newline at end of file |
| 1 | 32 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,56 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui.theme |
|
| 18 |
+ |
|
| 19 |
+import androidx.compose.foundation.* |
|
| 20 |
+import androidx.compose.material3.* |
|
| 21 |
+import androidx.compose.runtime.* |
|
| 22 |
+import androidx.compose.ui.* |
|
| 23 |
+ |
|
| 24 |
+/** |
|
| 25 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:20 |
|
| 26 |
+ */ |
|
| 27 |
+ |
|
| 28 |
+val DarkColor = darkColorScheme( |
|
| 29 |
+ primary = primaryDark, |
|
| 30 |
+ secondary = primaryDarkDark, |
|
| 31 |
+ tertiary = primaryDarkerDark, |
|
| 32 |
+ onPrimary = accentDark, |
|
| 33 |
+ onSecondary = black |
|
| 34 |
+) |
|
| 35 |
+ |
|
| 36 |
+val LightColor = lightColorScheme( |
|
| 37 |
+ primary = primaryLight, |
|
| 38 |
+ secondary = primaryDarkLight, |
|
| 39 |
+ tertiary = primaryDarkerLight, |
|
| 40 |
+ onPrimary = accentLight, |
|
| 41 |
+ onSecondary = black |
|
| 42 |
+) |
|
| 43 |
+ |
|
| 44 |
+@Composable |
|
| 45 |
+fun AudioNoteTheme( |
|
| 46 |
+ isDarkTheme:Boolean = isSystemInDarkTheme(), |
|
| 47 |
+ content: @Composable () -> Unit |
|
| 48 |
+) {
|
|
| 49 |
+ val color = if (isDarkTheme) DarkColor else LightColor |
|
| 50 |
+ |
|
| 51 |
+ MaterialTheme( |
|
| 52 |
+ colorScheme = color, |
|
| 53 |
+ typography = typography, |
|
| 54 |
+ content = content |
|
| 55 |
+ ) |
|
| 56 |
+} |
|
| 0 | 57 |
\ No newline at end of file |
| 1 | 58 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,43 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.ui.theme |
|
| 18 |
+ |
|
| 19 |
+import androidx.compose.material3.Typography |
|
| 20 |
+ |
|
| 21 |
+/** |
|
| 22 |
+ * Created by MJ Jacobs on 2024/12/28 at 13:24 |
|
| 23 |
+ */ |
|
| 24 |
+ |
|
| 25 |
+// Setting material theme typography |
|
| 26 |
+val typography = Typography( |
|
| 27 |
+ /** Other default text styles to override |
|
| 28 |
+ * titleLarge = TextStyle( |
|
| 29 |
+ * fontFamily = FontFamily.Default, |
|
| 30 |
+ * fontWeight = FontWeight.Normal, |
|
| 31 |
+ * fontSize = 22.sp, |
|
| 32 |
+ * lineHeight = 28.sp, |
|
| 33 |
+ * letterSpacing = 0.sp |
|
| 34 |
+ * ), |
|
| 35 |
+ * labelSmall = TextStyle( |
|
| 36 |
+ * fontFamily = FontFamily.Default, |
|
| 37 |
+ * fontWeight = FontWeight.Medium, |
|
| 38 |
+ * fontSize = 11.sp, |
|
| 39 |
+ * lineHeight = 16.sp, |
|
| 40 |
+ * letterSpacing = 0.5.sp |
|
| 41 |
+ * ) |
|
| 42 |
+ */ |
|
| 43 |
+) |
|
| 0 | 44 |
\ No newline at end of file |
| 1 | 45 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,28 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.utils |
|
| 18 |
+ |
|
| 19 |
+import androidx.room.TypeConverter |
|
| 20 |
+import java.util.* |
|
| 21 |
+ |
|
| 22 |
+class Converters {
|
|
| 23 |
+ @TypeConverter |
|
| 24 |
+ fun fromTimeStamp(value: Long) = Date(value) |
|
| 25 |
+ |
|
| 26 |
+ @TypeConverter |
|
| 27 |
+ fun dateToTimeStamp(date: Date) = date.time |
|
| 28 |
+} |
|
| 0 | 29 |
\ No newline at end of file |
| 1 | 30 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.utils |
|
| 18 |
+ |
|
| 19 |
+enum class UIState {
|
|
| 20 |
+ LOADING, |
|
| 21 |
+ HAS_DATA, |
|
| 22 |
+ EMPTY |
|
| 23 |
+} |
|
| 24 |
+ |
|
| 25 |
+enum class ReminderAvailableState {
|
|
| 26 |
+ HAS_REMINDER, |
|
| 27 |
+ NO_REMINDER |
|
| 28 |
+} |
|
| 29 |
+ |
|
| 30 |
+enum class ReminderCompletionState {
|
|
| 31 |
+ COMPLETED, |
|
| 32 |
+ ONGOING |
|
| 33 |
+} |
|
| 0 | 34 |
\ No newline at end of file |
| 1 | 35 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,72 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.utils |
|
| 18 |
+ |
|
| 19 |
+import android.app.Activity |
|
| 20 |
+import android.content.Context |
|
| 21 |
+import android.os.Bundle |
|
| 22 |
+import android.view.View |
|
| 23 |
+import android.view.WindowManager |
|
| 24 |
+import android.view.inputmethod.InputMethodManager |
|
| 25 |
+import android.widget.Toast |
|
| 26 |
+import androidx.annotation.IdRes |
|
| 27 |
+import androidx.core.content.res.ResourcesCompat |
|
| 28 |
+import androidx.datastore.preferences.preferencesDataStore |
|
| 29 |
+import androidx.fragment.app.Fragment |
|
| 30 |
+import androidx.navigation.NavController |
|
| 31 |
+import androidx.navigation.NavDirections |
|
| 32 |
+ |
|
| 33 |
+object Extensions {
|
|
| 34 |
+ fun Fragment.flags(color: Int) {
|
|
| 35 |
+ val window = requireActivity().window |
|
| 36 |
+ window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) |
|
| 37 |
+// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) |
|
| 38 |
+ window.statusBarColor = ResourcesCompat.getColor(resources, color, null) |
|
| 39 |
+ } |
|
| 40 |
+ |
|
| 41 |
+ fun Fragment.showToast(message: String) {
|
|
| 42 |
+ Toast.makeText( |
|
| 43 |
+ requireContext(), |
|
| 44 |
+ message, |
|
| 45 |
+ Toast.LENGTH_LONG |
|
| 46 |
+ ).show() |
|
| 47 |
+ } |
|
| 48 |
+ |
|
| 49 |
+ val Context.dataStore by preferencesDataStore(name = "com.certified.audionotes.preferences") |
|
| 50 |
+ |
|
| 51 |
+ fun View.hideKeyboardFrom(context: Context) {
|
|
| 52 |
+ val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager |
|
| 53 |
+ imm.hideSoftInputFromWindow(windowToken, 0) |
|
| 54 |
+ } |
|
| 55 |
+ |
|
| 56 |
+ fun View.showKeyboardFor(context: Context) {
|
|
| 57 |
+ val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager |
|
| 58 |
+ imm.showSoftInput(this, 0) |
|
| 59 |
+ } |
|
| 60 |
+ |
|
| 61 |
+ fun NavController.safeNavigate(direction: NavDirections) {
|
|
| 62 |
+ currentDestination?.getAction(direction.actionId)?.run { navigate(direction) }
|
|
| 63 |
+ } |
|
| 64 |
+ |
|
| 65 |
+ fun NavController.safeNavigate( |
|
| 66 |
+ @IdRes currentDestinationId: Int, |
|
| 67 |
+ @IdRes id: Int, |
|
| 68 |
+ args: Bundle? = null |
|
| 69 |
+ ) {
|
|
| 70 |
+ if (currentDestinationId == currentDestination?.id) navigate(id, args) |
|
| 71 |
+ } |
|
| 72 |
+} |
|
| 0 | 73 |
\ No newline at end of file |
| 1 | 74 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.utils |
|
| 18 |
+ |
|
| 19 |
+fun main() {
|
|
| 20 |
+ val i = "00:08:18" |
|
| 21 |
+ val time = i.filter { it.isDigit() }.toLong()
|
|
| 22 |
+ val sec = time % 60 |
|
| 23 |
+ val minute = (time % 3600) / 60 |
|
| 24 |
+ println("Time: $time, Minute: $minute, Second: $sec")
|
|
| 25 |
+// print(isEven(201)) |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+fun isEven(number: Int): String {
|
|
| 29 |
+ return when (number % 2) {
|
|
| 30 |
+ 0 -> "true" |
|
| 31 |
+ else -> "false" |
|
| 32 |
+ } |
|
| 33 |
+} |
|
| 0 | 34 |
\ No newline at end of file |
| 1 | 35 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,101 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.utils |
|
| 18 |
+ |
|
| 19 |
+import android.app.NotificationManager |
|
| 20 |
+import android.content.Context |
|
| 21 |
+import android.media.RingtoneManager |
|
| 22 |
+import android.os.Build |
|
| 23 |
+import androidx.core.app.NotificationCompat |
|
| 24 |
+import androidx.core.app.NotificationCompat.DEFAULT_ALL |
|
| 25 |
+import androidx.core.app.NotificationCompat.PRIORITY_HIGH |
|
| 26 |
+import androidx.core.content.res.ResourcesCompat |
|
| 27 |
+import androidx.navigation.NavDeepLinkBuilder |
|
| 28 |
+import androidx.work.Worker |
|
| 29 |
+import androidx.work.WorkerParameters |
|
| 30 |
+import com.certified.audionote.R |
|
| 31 |
+import com.certified.audionote.model.Note |
|
| 32 |
+import com.certified.audionote.ui.EditNoteFragmentArgs |
|
| 33 |
+import com.certified.audionote.ui.main.MainActivity |
|
| 34 |
+ |
|
| 35 |
+class NotificationWorker(private val appContext: Context, workerParams: WorkerParameters) : |
|
| 36 |
+ Worker(appContext, workerParams) {
|
|
| 37 |
+ override fun doWork(): Result {
|
|
| 38 |
+ |
|
| 39 |
+ val noteId = inputData.getInt("noteId", 0)
|
|
| 40 |
+ val noteTitle = inputData.getString("noteTitle")
|
|
| 41 |
+ val noteDescription = inputData.getString("noteDescription")
|
|
| 42 |
+ val noteColor = inputData.getInt("noteColor", -1)
|
|
| 43 |
+ val noteLastModificationDate = inputData.getLong("noteLastModificationDate", -1L)
|
|
| 44 |
+ val noteSize = inputData.getString("noteSize")
|
|
| 45 |
+ val noteAudioLength = inputData.getLong("noteAudioLength", 0L)
|
|
| 46 |
+ val noteFilePath = inputData.getString("noteFilePath")
|
|
| 47 |
+ val noteStarted = inputData.getBoolean("noteStarted", false)
|
|
| 48 |
+ val noteReminder = inputData.getLong("noteReminder", -1L)
|
|
| 49 |
+ |
|
| 50 |
+ val note = Note( |
|
| 51 |
+ noteTitle!!, |
|
| 52 |
+ noteDescription!!, |
|
| 53 |
+ noteColor, |
|
| 54 |
+ noteLastModificationDate, |
|
| 55 |
+ noteSize!!, |
|
| 56 |
+ noteAudioLength, |
|
| 57 |
+ noteFilePath!!, |
|
| 58 |
+ noteStarted, |
|
| 59 |
+ noteReminder, |
|
| 60 |
+ noteId, |
|
| 61 |
+ ) |
|
| 62 |
+ notifyUser(appContext, note) |
|
| 63 |
+ |
|
| 64 |
+ return Result.success() |
|
| 65 |
+ } |
|
| 66 |
+ |
|
| 67 |
+ private fun notifyUser(context: Context, note: Note) {
|
|
| 68 |
+ |
|
| 69 |
+ val defaultSoundUri = |
|
| 70 |
+ RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) |
|
| 71 |
+ val notificationManager = |
|
| 72 |
+ context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager |
|
| 73 |
+ |
|
| 74 |
+ val pendingIntent = |
|
| 75 |
+ NavDeepLinkBuilder(context) |
|
| 76 |
+ .setGraph(R.navigation.navigation) |
|
| 77 |
+ .setDestination( |
|
| 78 |
+ R.id.editNoteFragment, |
|
| 79 |
+ EditNoteFragmentArgs(note).toBundle() |
|
| 80 |
+ ) |
|
| 81 |
+ .setComponentName(MainActivity::class.java) |
|
| 82 |
+ .createPendingIntent() |
|
| 83 |
+ |
|
| 84 |
+ val notificationBuilder = |
|
| 85 |
+ NotificationCompat.Builder(context, context.getString(R.string.channelId)) |
|
| 86 |
+ .setSmallIcon(R.drawable.ic_baseline_notifications_24) |
|
| 87 |
+ .setContentTitle(note.title) |
|
| 88 |
+ .setContentText("Hi there, it's time to check out ${note.title}")
|
|
| 89 |
+ .setColor(ResourcesCompat.getColor(context.resources, R.color.primary, null)) |
|
| 90 |
+ .setSound(defaultSoundUri) |
|
| 91 |
+ .setDefaults(DEFAULT_ALL) |
|
| 92 |
+ .setContentIntent(pendingIntent) |
|
| 93 |
+ .setPriority(PRIORITY_HIGH) |
|
| 94 |
+ .setAutoCancel(true) |
|
| 95 |
+ |
|
| 96 |
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) |
|
| 97 |
+ notificationBuilder.setChannelId(context.getString(R.string.channelId)) |
|
| 98 |
+ |
|
| 99 |
+ notificationManager.notify(note.id, notificationBuilder.build()) |
|
| 100 |
+ } |
|
| 101 |
+} |
|
| 0 | 102 |
\ No newline at end of file |
| 1 | 103 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,23 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.utils |
|
| 18 |
+ |
|
| 19 |
+import androidx.datastore.preferences.core.booleanPreferencesKey |
|
| 20 |
+ |
|
| 21 |
+object PreferenceKeys {
|
|
| 22 |
+ val FIRST_TIME_LOGIN = booleanPreferencesKey("FIRST_TIME_LOGIN")
|
|
| 23 |
+} |
|
| 0 | 24 |
\ No newline at end of file |
| 1 | 25 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,113 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.utils |
|
| 18 |
+ |
|
| 19 |
+import android.app.Activity |
|
| 20 |
+import android.app.AlarmManager |
|
| 21 |
+import android.app.PendingIntent |
|
| 22 |
+import android.content.Context |
|
| 23 |
+import android.content.Intent |
|
| 24 |
+import android.os.Build |
|
| 25 |
+import android.util.Log |
|
| 26 |
+import com.certified.audionote.R |
|
| 27 |
+import com.certified.audionote.model.Note |
|
| 28 |
+import com.certified.audionote.ui.AlertReceiver |
|
| 29 |
+import java.text.SimpleDateFormat |
|
| 30 |
+import java.util.Calendar |
|
| 31 |
+import java.util.Date |
|
| 32 |
+import java.util.Locale |
|
| 33 |
+import java.util.concurrent.TimeUnit |
|
| 34 |
+ |
|
| 35 |
+val colors = listOf( |
|
| 36 |
+ -504764, -740056, -1544140, -2277816, -3246217, -4024195, |
|
| 37 |
+ -4224594, -7305542, -7551917, -7583749, -10712898, -10896368, -10965321, |
|
| 38 |
+ -11419154, -14654801 |
|
| 39 |
+) |
|
| 40 |
+ |
|
| 41 |
+fun filePath(activity: Activity) = activity.getExternalFilesDir("/")?.absolutePath
|
|
| 42 |
+ |
|
| 43 |
+fun currentDate(): Calendar = Calendar.getInstance() |
|
| 44 |
+ |
|
| 45 |
+fun formatDate(date: Long, context: Context): String {
|
|
| 46 |
+ |
|
| 47 |
+ val now = Date() |
|
| 48 |
+ val seconds = TimeUnit.MILLISECONDS.toSeconds(now.time - date) |
|
| 49 |
+ val minutes = TimeUnit.MILLISECONDS.toMinutes(now.time - date) |
|
| 50 |
+ val hours = TimeUnit.MILLISECONDS.toHours(now.time - date) |
|
| 51 |
+ val days = TimeUnit.MILLISECONDS.toDays(now.time - date) |
|
| 52 |
+ |
|
| 53 |
+ return when {
|
|
| 54 |
+ seconds < 60 -> context.getString(R.string.just_now) |
|
| 55 |
+ minutes == 1L -> context.getString(R.string.a_minute_ago) |
|
| 56 |
+ minutes in 2..59L -> "$minutes ${context.getString(R.string.minutes_ago)}"
|
|
| 57 |
+ hours == 1L -> context.getString(R.string.an_hour_ago) |
|
| 58 |
+ hours in 2..23 -> "$hours ${context.getString(R.string.hours_ago)}"
|
|
| 59 |
+ days == 1L -> context.getString(R.string.a_day_ago) |
|
| 60 |
+ else -> formatSimpleDate(date) |
|
| 61 |
+ } |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+fun formatReminderDate(date: Long): String = |
|
| 65 |
+ SimpleDateFormat("dd MMM, yyyy h:mm a", Locale.getDefault()).format(date)
|
|
| 66 |
+ |
|
| 67 |
+fun formatSimpleDate(date: Long): String = |
|
| 68 |
+ SimpleDateFormat("dd/MM/yy", Locale.getDefault()).format(date)
|
|
| 69 |
+ |
|
| 70 |
+fun formatDateOnly(date: Long): String = |
|
| 71 |
+ SimpleDateFormat("dd MMM, yyyy", Locale.getDefault()).format(date)
|
|
| 72 |
+ |
|
| 73 |
+fun formatTime(date: Long): String = SimpleDateFormat("h:mm a", Locale.getDefault()).format(date)
|
|
| 74 |
+ |
|
| 75 |
+fun startAlarm(context: Context, time: Long, note: Note) {
|
|
| 76 |
+ val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager |
|
| 77 |
+ val intent = Intent(context, AlertReceiver::class.java) |
|
| 78 |
+ intent.apply {
|
|
| 79 |
+ putExtra("noteId", note.id)
|
|
| 80 |
+ putExtra("noteTitle", note.title)
|
|
| 81 |
+ putExtra("noteDescription", note.description)
|
|
| 82 |
+ putExtra("noteColor", note.color)
|
|
| 83 |
+ putExtra("noteLastModificationDate", note.lastModificationDate)
|
|
| 84 |
+ putExtra("noteSize", note.size)
|
|
| 85 |
+ putExtra("noteAudioLength", note.audioLength)
|
|
| 86 |
+ putExtra("noteFilePath", note.filePath)
|
|
| 87 |
+ putExtra("noteStarted", note.started)
|
|
| 88 |
+ putExtra("noteReminder", note.reminder)
|
|
| 89 |
+ } |
|
| 90 |
+ val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
| 91 |
+ PendingIntent.getBroadcast(context, note.id, intent, PendingIntent.FLAG_IMMUTABLE) |
|
| 92 |
+ } else {
|
|
| 93 |
+ PendingIntent.getBroadcast(context, note.id, intent, 0) |
|
| 94 |
+ } |
|
| 95 |
+ alarmManager.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent) |
|
| 96 |
+ Log.d("TAG", "startAlarm: Alarm started")
|
|
| 97 |
+} |
|
| 98 |
+ |
|
| 99 |
+fun cancelAlarm(context: Context, noteId: Int) {
|
|
| 100 |
+ val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager |
|
| 101 |
+ val intent = Intent(context, AlertReceiver::class.java) |
|
| 102 |
+ val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
| 103 |
+ PendingIntent.getBroadcast(context, noteId, intent, PendingIntent.FLAG_IMMUTABLE) |
|
| 104 |
+ } else {
|
|
| 105 |
+ PendingIntent.getBroadcast(context, noteId, intent, 0) |
|
| 106 |
+ } |
|
| 107 |
+ alarmManager.cancel(pendingIntent) |
|
| 108 |
+ Log.d("TAG", "cancelAlarm: Alarm canceled")
|
|
| 109 |
+} |
|
| 110 |
+ |
|
| 111 |
+fun roundOffDecimal(number: Double): String {
|
|
| 112 |
+ return "%.2f".format(number) |
|
| 113 |
+} |
|
| 0 | 114 |
\ No newline at end of file |
| 1 | 115 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,77 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote.utils |
|
| 18 |
+ |
|
| 19 |
+import android.app.Activity |
|
| 20 |
+import androidx.compose.runtime.* |
|
| 21 |
+import androidx.window.layout.* |
|
| 22 |
+ |
|
| 23 |
+/** |
|
| 24 |
+ * Created by MJ Jacobs on 2024/12/28 at 14:04 |
|
| 25 |
+ */ |
|
| 26 |
+ |
|
| 27 |
+@Composable |
|
| 28 |
+fun calculateWindowSize( |
|
| 29 |
+ activity: Activity, |
|
| 30 |
+ windowWidthSizeClassChange: @Composable (windowSize: WindowSizeClass) -> Unit = {},
|
|
| 31 |
+ windowHeightSizeClassChange: @Composable (windowSize: WindowSizeClass) -> Unit = {},
|
|
| 32 |
+) {
|
|
| 33 |
+ val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity) |
|
| 34 |
+ |
|
| 35 |
+ val widthDp = metrics.bounds.width() / activity.resources.displayMetrics.density |
|
| 36 |
+ val heightDp = metrics.bounds.height() / activity.resources.displayMetrics.density |
|
| 37 |
+ |
|
| 38 |
+ when {
|
|
| 39 |
+ widthDp < 600f -> {
|
|
| 40 |
+ // 99.96% of phones in portrait |
|
| 41 |
+ windowWidthSizeClassChange(WindowSizeClass.COMPACT) |
|
| 42 |
+ } |
|
| 43 |
+ |
|
| 44 |
+ widthDp < 840f -> {
|
|
| 45 |
+ // 93.73% of tablets in portrait |
|
| 46 |
+ windowWidthSizeClassChange(WindowSizeClass.MEDIUM) |
|
| 47 |
+ } |
|
| 48 |
+ |
|
| 49 |
+ else -> {
|
|
| 50 |
+ // 97.22% of tablets in landscape |
|
| 51 |
+ windowWidthSizeClassChange(WindowSizeClass.EXPANDED) |
|
| 52 |
+ } |
|
| 53 |
+ } |
|
| 54 |
+ |
|
| 55 |
+ when {
|
|
| 56 |
+ heightDp < 480f -> {
|
|
| 57 |
+ // 99.78 of phones in landscape |
|
| 58 |
+ windowHeightSizeClassChange(WindowSizeClass.COMPACT) |
|
| 59 |
+ } |
|
| 60 |
+ |
|
| 61 |
+ heightDp < 900f -> {
|
|
| 62 |
+ // 96.56% of tablets in landscape and 97.59% of phones in portrait |
|
| 63 |
+ windowHeightSizeClassChange(WindowSizeClass.MEDIUM) |
|
| 64 |
+ } |
|
| 65 |
+ |
|
| 66 |
+ else -> {
|
|
| 67 |
+ // 94.25% of tablets in portrait |
|
| 68 |
+ windowHeightSizeClassChange(WindowSizeClass.EXPANDED) |
|
| 69 |
+ } |
|
| 70 |
+ } |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 73 |
+enum class WindowSizeClass {
|
|
| 74 |
+ COMPACT, |
|
| 75 |
+ MEDIUM, |
|
| 76 |
+ EXPANDED |
|
| 77 |
+} |
|
| 0 | 78 |
\ No newline at end of file |
| 1 | 79 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,31 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<set xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 18 |
+ |
|
| 19 |
+ <alpha |
|
| 20 |
+ android:duration="300" |
|
| 21 |
+ android:fromAlpha="0" |
|
| 22 |
+ android:toAlpha="1" /> |
|
| 23 |
+ <scale |
|
| 24 |
+ android:duration="300" |
|
| 25 |
+ android:pivotX="50%" |
|
| 26 |
+ android:pivotY="50%" |
|
| 27 |
+ android:fromXScale="40%" |
|
| 28 |
+ android:fromYScale="40%" |
|
| 29 |
+ android:toXScale="100%" |
|
| 30 |
+ android:toYScale="100%" /> |
|
| 31 |
+</set> |
|
| 0 | 32 |
\ No newline at end of file |
| 1 | 33 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,31 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<set xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 18 |
+ |
|
| 19 |
+ <alpha |
|
| 20 |
+ android:duration="300" |
|
| 21 |
+ android:fromAlpha="1" |
|
| 22 |
+ android:toAlpha="0" /> |
|
| 23 |
+ <scale |
|
| 24 |
+ android:duration="300" |
|
| 25 |
+ android:pivotX="50%" |
|
| 26 |
+ android:pivotY="50%" |
|
| 27 |
+ android:fromXScale="100%" |
|
| 28 |
+ android:fromYScale="100%" |
|
| 29 |
+ android:toXScale="40%" |
|
| 30 |
+ android:toYScale="40%" /> |
|
| 31 |
+</set> |
|
| 0 | 32 |
\ No newline at end of file |
| 1 | 33 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,24 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<set xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 18 |
+ <translate |
|
| 19 |
+ android:duration="300" |
|
| 20 |
+ android:fromXDelta="100%" |
|
| 21 |
+ android:fromYDelta="0%" |
|
| 22 |
+ android:toXDelta="0%" |
|
| 23 |
+ android:toYDelta="0%" /> |
|
| 24 |
+</set> |
|
| 0 | 25 |
\ No newline at end of file |
| 1 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,24 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<set xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 18 |
+ <translate |
|
| 19 |
+ android:duration="300" |
|
| 20 |
+ android:fromXDelta="0%" |
|
| 21 |
+ android:fromYDelta="0%" |
|
| 22 |
+ android:toXDelta="100%" |
|
| 23 |
+ android:toYDelta="0%" /> |
|
| 24 |
+</set> |
|
| 0 | 25 |
\ No newline at end of file |
| 1 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,46 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:aapt="http://schemas.android.com/aapt" |
|
| 19 |
+ android:width="108dp" |
|
| 20 |
+ android:height="108dp" |
|
| 21 |
+ android:viewportWidth="108" |
|
| 22 |
+ android:viewportHeight="108"> |
|
| 23 |
+ <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> |
|
| 24 |
+ <aapt:attr name="android:fillColor"> |
|
| 25 |
+ <gradient |
|
| 26 |
+ android:endX="85.84757" |
|
| 27 |
+ android:endY="92.4963" |
|
| 28 |
+ android:startX="42.9492" |
|
| 29 |
+ android:startY="49.59793" |
|
| 30 |
+ android:type="linear"> |
|
| 31 |
+ <item |
|
| 32 |
+ android:color="#44000000" |
|
| 33 |
+ android:offset="0.0" /> |
|
| 34 |
+ <item |
|
| 35 |
+ android:color="#00000000" |
|
| 36 |
+ android:offset="1.0" /> |
|
| 37 |
+ </gradient> |
|
| 38 |
+ </aapt:attr> |
|
| 39 |
+ </path> |
|
| 40 |
+ <path |
|
| 41 |
+ android:fillColor="#FFFFFF" |
|
| 42 |
+ android:fillType="nonZero" |
|
| 43 |
+ android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" |
|
| 44 |
+ android:strokeWidth="1" |
|
| 45 |
+ android:strokeColor="#00000000" /> |
|
| 46 |
+</vector> |
|
| 0 | 47 |
\ No newline at end of file |
| 3 | 50 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M10.54,14.53L8.41,12.4l-1.06,1.06 3.18,3.18 6,-6 -1.06,-1.06zM17.337,1.81l4.607,3.845 -1.28,1.535 -4.61,-3.843zM6.663,1.81l1.282,1.536L3.337,7.19l-1.28,-1.536zM12,4c-4.97,0 -9,4.03 -9,9s4.03,9 9,9 9,-4.03 9,-9 -4.03,-9 -9,-9zM12,20c-3.86,0 -7,-3.14 -7,-7s3.14,-7 7,-7 7,3.14 7,7 -3.14,7 -7,7z" |
|
| 24 |
+ android:fillColor="#000000"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M16.62,2.99c-0.49,-0.49 -1.28,-0.49 -1.77,0L6.54,11.3c-0.39,0.39 -0.39,1.02 0,1.41l8.31,8.31c0.49,0.49 1.28,0.49 1.77,0s0.49,-1.28 0,-1.77L9.38,12l7.25,-7.25c0.48,-0.48 0.48,-1.28 -0.01,-1.76z" |
|
| 24 |
+ android:fillColor="@color/black_day_white_night"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,28 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="200dp" |
|
| 19 |
+ android:height="200dp" |
|
| 20 |
+ android:viewportWidth="200" |
|
| 21 |
+ android:viewportHeight="200"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M100,100m-100,0a100,100 0,1 1,200 0a100,100 0,1 1,-200 0" |
|
| 24 |
+ android:fillColor="#939094"/> |
|
| 25 |
+ <path |
|
| 26 |
+ android:pathData="M70,74.86V125.14C70,128.974 75.145,131.304 79.108,129.217L127.25,104.077C130.917,102.184 130.917,97.816 127.25,95.875L79.108,70.783C75.145,68.696 70,71.026 70,74.86Z" |
|
| 27 |
+ android:fillColor="#313033"/> |
|
| 28 |
+</vector> |
| 0 | 29 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="200dp" |
|
| 19 |
+ android:height="200dp" |
|
| 20 |
+ android:viewportWidth="200" |
|
| 21 |
+ android:viewportHeight="200"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M100,100m-98.5,0a98.5,98.5 0,1 1,197 0a98.5,98.5 0,1 1,-197 0" |
|
| 24 |
+ android:strokeWidth="3" |
|
| 25 |
+ android:fillColor="#00000000" |
|
| 26 |
+ android:strokeColor="#EFB8C8"/> |
|
| 27 |
+ <path |
|
| 28 |
+ android:pathData="M100,100m-85,0a85,85 0,1 1,170 0a85,85 0,1 1,-170 0" |
|
| 29 |
+ android:fillColor="#EFB8C8"/> |
|
| 30 |
+ <path |
|
| 31 |
+ android:pathData="M70,74.86V125.14C70,128.974 75.145,131.304 79.108,129.217L127.25,104.077C130.917,102.184 130.917,97.816 127.25,95.875L79.108,70.783C75.145,68.696 70,71.026 70,74.86Z" |
|
| 32 |
+ android:fillColor="#ffffff"/> |
|
| 33 |
+</vector> |
| 0 | 34 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,26 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24" |
|
| 22 |
+ android:tint="?attr/colorControlNormal"> |
|
| 23 |
+ <path |
|
| 24 |
+ android:fillColor="@android:color/white" |
|
| 25 |
+ android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/> |
|
| 26 |
+</vector> |
| 0 | 27 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="24dp" |
|
| 19 |
+ android:height="24dp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M20,8.69L20,4h-4.69L12,0.69 8.69,4L4,4v4.69L0.69,12 4,15.31L4,20h4.69L12,23.31 15.31,20L20,20v-4.69L23.31,12 20,8.69zM18,14.48L18,18h-3.52L12,20.48 9.52,18L6,18v-3.52L3.52,12 6,9.52L6,6h3.52L12,3.52 14.48,6L18,6v3.52L20.48,12 18,14.48zM12,6v12c3.31,0 6,-2.69 6,-6s-2.69,-6 -6,-6z" |
|
| 24 |
+ android:fillColor="@color/black_day_white_night"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="24dp" |
|
| 19 |
+ android:height="24dp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M8.7,15.9L4.8,12l3.9,-3.9c0.39,-0.39 0.39,-1.01 0,-1.4 -0.39,-0.39 -1.01,-0.39 -1.4,0l-4.59,4.59c-0.39,0.39 -0.39,1.02 0,1.41l4.59,4.6c0.39,0.39 1.01,0.39 1.4,0 0.39,-0.39 0.39,-1.01 0,-1.4zM15.3,15.9l3.9,-3.9 -3.9,-3.9c-0.39,-0.39 -0.39,-1.01 0,-1.4 0.39,-0.39 1.01,-0.39 1.4,0l4.59,4.59c0.39,0.39 0.39,1.02 0,1.41l-4.59,4.6c-0.39,0.39 -1.01,0.39 -1.4,0 -0.39,-0.39 -0.39,-1.01 0,-1.4z" |
|
| 24 |
+ android:fillColor="@color/black_day_white_night"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="24dp" |
|
| 19 |
+ android:height="24dp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M11,23.59v-3.6c-5.01,-0.26 -9,-4.42 -9,-9.49C2,5.26 6.26,1 11.5,1S21,5.26 21,10.5c0,4.95 -3.44,9.93 -8.57,12.4l-1.43,0.69zM11.5,3C7.36,3 4,6.36 4,10.5S7.36,18 11.5,18L13,18v2.3c3.64,-2.3 6,-6.08 6,-9.8C19,6.36 15.64,3 11.5,3zM10.5,14.5h2v2h-2zM12.5,13h-2c0,-3.25 3,-3 3,-5 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2h-2c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,2.5 -3,2.75 -3,5z" |
|
| 24 |
+ android:fillColor="@color/black_day_white_night"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M16,9v10H8V9h8m-1.5,-6h-5l-1,1H5v2h14V4h-3.5l-1,-1zM18,7H6v12c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7z" |
|
| 24 |
+ android:fillColor="#000000"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M9,16.2l-3.5,-3.5c-0.39,-0.39 -1.01,-0.39 -1.4,0 -0.39,0.39 -0.39,1.01 0,1.4l4.19,4.19c0.39,0.39 1.02,0.39 1.41,0L20.3,7.7c0.39,-0.39 0.39,-1.01 0,-1.4 -0.39,-0.39 -1.01,-0.39 -1.4,0L9,16.2z" |
|
| 24 |
+ android:fillColor="#000000"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="24dp" |
|
| 19 |
+ android:height="24dp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z" |
|
| 24 |
+ android:fillColor="@color/black_day_white_night"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,186 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
+<!-- |
|
| 3 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 4 |
+ ~ |
|
| 5 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ ~ you may not use this file except in compliance with the License. |
|
| 7 |
+ ~ You may obtain a copy of the License at |
|
| 8 |
+ ~ |
|
| 9 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ ~ |
|
| 11 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ ~ See the License for the specific language governing permissions and |
|
| 15 |
+ ~ limitations under the License. |
|
| 16 |
+ --> |
|
| 17 |
+ |
|
| 18 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 19 |
+ android:width="108dp" |
|
| 20 |
+ android:height="108dp" |
|
| 21 |
+ android:viewportWidth="108" |
|
| 22 |
+ android:viewportHeight="108"> |
|
| 23 |
+ <path |
|
| 24 |
+ android:fillColor="#3DDC84" |
|
| 25 |
+ android:pathData="M0,0h108v108h-108z" /> |
|
| 26 |
+ <path |
|
| 27 |
+ android:fillColor="#00000000" |
|
| 28 |
+ android:pathData="M9,0L9,108" |
|
| 29 |
+ android:strokeWidth="0.8" |
|
| 30 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 31 |
+ <path |
|
| 32 |
+ android:fillColor="#00000000" |
|
| 33 |
+ android:pathData="M19,0L19,108" |
|
| 34 |
+ android:strokeWidth="0.8" |
|
| 35 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 36 |
+ <path |
|
| 37 |
+ android:fillColor="#00000000" |
|
| 38 |
+ android:pathData="M29,0L29,108" |
|
| 39 |
+ android:strokeWidth="0.8" |
|
| 40 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 41 |
+ <path |
|
| 42 |
+ android:fillColor="#00000000" |
|
| 43 |
+ android:pathData="M39,0L39,108" |
|
| 44 |
+ android:strokeWidth="0.8" |
|
| 45 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 46 |
+ <path |
|
| 47 |
+ android:fillColor="#00000000" |
|
| 48 |
+ android:pathData="M49,0L49,108" |
|
| 49 |
+ android:strokeWidth="0.8" |
|
| 50 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 51 |
+ <path |
|
| 52 |
+ android:fillColor="#00000000" |
|
| 53 |
+ android:pathData="M59,0L59,108" |
|
| 54 |
+ android:strokeWidth="0.8" |
|
| 55 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 56 |
+ <path |
|
| 57 |
+ android:fillColor="#00000000" |
|
| 58 |
+ android:pathData="M69,0L69,108" |
|
| 59 |
+ android:strokeWidth="0.8" |
|
| 60 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 61 |
+ <path |
|
| 62 |
+ android:fillColor="#00000000" |
|
| 63 |
+ android:pathData="M79,0L79,108" |
|
| 64 |
+ android:strokeWidth="0.8" |
|
| 65 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 66 |
+ <path |
|
| 67 |
+ android:fillColor="#00000000" |
|
| 68 |
+ android:pathData="M89,0L89,108" |
|
| 69 |
+ android:strokeWidth="0.8" |
|
| 70 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 71 |
+ <path |
|
| 72 |
+ android:fillColor="#00000000" |
|
| 73 |
+ android:pathData="M99,0L99,108" |
|
| 74 |
+ android:strokeWidth="0.8" |
|
| 75 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 76 |
+ <path |
|
| 77 |
+ android:fillColor="#00000000" |
|
| 78 |
+ android:pathData="M0,9L108,9" |
|
| 79 |
+ android:strokeWidth="0.8" |
|
| 80 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 81 |
+ <path |
|
| 82 |
+ android:fillColor="#00000000" |
|
| 83 |
+ android:pathData="M0,19L108,19" |
|
| 84 |
+ android:strokeWidth="0.8" |
|
| 85 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 86 |
+ <path |
|
| 87 |
+ android:fillColor="#00000000" |
|
| 88 |
+ android:pathData="M0,29L108,29" |
|
| 89 |
+ android:strokeWidth="0.8" |
|
| 90 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 91 |
+ <path |
|
| 92 |
+ android:fillColor="#00000000" |
|
| 93 |
+ android:pathData="M0,39L108,39" |
|
| 94 |
+ android:strokeWidth="0.8" |
|
| 95 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 96 |
+ <path |
|
| 97 |
+ android:fillColor="#00000000" |
|
| 98 |
+ android:pathData="M0,49L108,49" |
|
| 99 |
+ android:strokeWidth="0.8" |
|
| 100 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 101 |
+ <path |
|
| 102 |
+ android:fillColor="#00000000" |
|
| 103 |
+ android:pathData="M0,59L108,59" |
|
| 104 |
+ android:strokeWidth="0.8" |
|
| 105 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 106 |
+ <path |
|
| 107 |
+ android:fillColor="#00000000" |
|
| 108 |
+ android:pathData="M0,69L108,69" |
|
| 109 |
+ android:strokeWidth="0.8" |
|
| 110 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 111 |
+ <path |
|
| 112 |
+ android:fillColor="#00000000" |
|
| 113 |
+ android:pathData="M0,79L108,79" |
|
| 114 |
+ android:strokeWidth="0.8" |
|
| 115 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 116 |
+ <path |
|
| 117 |
+ android:fillColor="#00000000" |
|
| 118 |
+ android:pathData="M0,89L108,89" |
|
| 119 |
+ android:strokeWidth="0.8" |
|
| 120 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 121 |
+ <path |
|
| 122 |
+ android:fillColor="#00000000" |
|
| 123 |
+ android:pathData="M0,99L108,99" |
|
| 124 |
+ android:strokeWidth="0.8" |
|
| 125 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 126 |
+ <path |
|
| 127 |
+ android:fillColor="#00000000" |
|
| 128 |
+ android:pathData="M19,29L89,29" |
|
| 129 |
+ android:strokeWidth="0.8" |
|
| 130 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 131 |
+ <path |
|
| 132 |
+ android:fillColor="#00000000" |
|
| 133 |
+ android:pathData="M19,39L89,39" |
|
| 134 |
+ android:strokeWidth="0.8" |
|
| 135 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 136 |
+ <path |
|
| 137 |
+ android:fillColor="#00000000" |
|
| 138 |
+ android:pathData="M19,49L89,49" |
|
| 139 |
+ android:strokeWidth="0.8" |
|
| 140 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 141 |
+ <path |
|
| 142 |
+ android:fillColor="#00000000" |
|
| 143 |
+ android:pathData="M19,59L89,59" |
|
| 144 |
+ android:strokeWidth="0.8" |
|
| 145 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 146 |
+ <path |
|
| 147 |
+ android:fillColor="#00000000" |
|
| 148 |
+ android:pathData="M19,69L89,69" |
|
| 149 |
+ android:strokeWidth="0.8" |
|
| 150 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 151 |
+ <path |
|
| 152 |
+ android:fillColor="#00000000" |
|
| 153 |
+ android:pathData="M19,79L89,79" |
|
| 154 |
+ android:strokeWidth="0.8" |
|
| 155 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 156 |
+ <path |
|
| 157 |
+ android:fillColor="#00000000" |
|
| 158 |
+ android:pathData="M29,19L29,89" |
|
| 159 |
+ android:strokeWidth="0.8" |
|
| 160 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 161 |
+ <path |
|
| 162 |
+ android:fillColor="#00000000" |
|
| 163 |
+ android:pathData="M39,19L39,89" |
|
| 164 |
+ android:strokeWidth="0.8" |
|
| 165 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 166 |
+ <path |
|
| 167 |
+ android:fillColor="#00000000" |
|
| 168 |
+ android:pathData="M49,19L49,89" |
|
| 169 |
+ android:strokeWidth="0.8" |
|
| 170 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 171 |
+ <path |
|
| 172 |
+ android:fillColor="#00000000" |
|
| 173 |
+ android:pathData="M59,19L59,89" |
|
| 174 |
+ android:strokeWidth="0.8" |
|
| 175 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 176 |
+ <path |
|
| 177 |
+ android:fillColor="#00000000" |
|
| 178 |
+ android:pathData="M69,19L69,89" |
|
| 179 |
+ android:strokeWidth="0.8" |
|
| 180 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 181 |
+ <path |
|
| 182 |
+ android:fillColor="#00000000" |
|
| 183 |
+ android:pathData="M79,19L79,89" |
|
| 184 |
+ android:strokeWidth="0.8" |
|
| 185 |
+ android:strokeColor="#33FFFFFF" /> |
|
| 186 |
+</vector> |
| 0 | 187 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,9 @@ |
| 1 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 2 |
+ android:width="@dimen/_108sdp" |
|
| 3 |
+ android:height="@dimen/_108sdp" |
|
| 4 |
+ android:viewportWidth="108" |
|
| 5 |
+ android:viewportHeight="108"> |
|
| 6 |
+ <path |
|
| 7 |
+ android:pathData="M42,70.2C43.65,70.2 45,68.99 45,67.5V40.5C45,39.01 43.65,37.8 42,37.8C40.35,37.8 39,39.01 39,40.5V67.5C39,68.99 40.35,70.2 42,70.2ZM54,81C55.65,81 57,79.79 57,78.3V29.7C57,28.22 55.65,27 54,27C52.35,27 51,28.22 51,29.7V78.3C51,79.79 52.35,81 54,81ZM30,59.4C31.65,59.4 33,58.19 33,56.7V51.3C33,49.81 31.65,48.6 30,48.6C28.35,48.6 27,49.81 27,51.3V56.7C27,58.19 28.35,59.4 30,59.4ZM66,70.2C67.65,70.2 69,68.99 69,67.5V40.5C69,39.01 67.65,37.8 66,37.8C64.35,37.8 63,39.01 63,40.5V67.5C63,68.99 64.35,70.2 66,70.2ZM75,51.3V56.7C75,58.19 76.35,59.4 78,59.4C79.65,59.4 81,58.19 81,56.7V51.3C81,49.81 79.65,48.6 78,48.6C76.35,48.6 75,49.81 75,51.3Z" |
|
| 8 |
+ android:fillColor="#986977"/> |
|
| 9 |
+</vector> |
| 0 | 10 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="100dp" |
|
| 19 |
+ android:height="100dp" |
|
| 20 |
+ android:viewportWidth="100" |
|
| 21 |
+ android:viewportHeight="100"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M27.778,80C30.833,80 33.333,77.75 33.333,75V25C33.333,22.25 30.833,20 27.778,20C24.722,20 22.222,22.25 22.222,25V75C22.222,77.75 24.722,80 27.778,80ZM50,100C53.056,100 55.556,97.75 55.556,95V5C55.556,2.25 53.056,0 50,0C46.944,0 44.444,2.25 44.444,5V95C44.444,97.75 46.944,100 50,100ZM5.556,60C8.611,60 11.111,57.75 11.111,55V45C11.111,42.25 8.611,40 5.556,40C2.5,40 0,42.25 0,45V55C0,57.75 2.5,60 5.556,60ZM72.222,80C75.278,80 77.778,77.75 77.778,75V25C77.778,22.25 75.278,20 72.222,20C69.167,20 66.667,22.25 66.667,25V75C66.667,77.75 69.167,80 72.222,80ZM88.889,45V55C88.889,57.75 91.389,60 94.444,60C97.5,60 100,57.75 100,55V45C100,42.25 97.5,40 94.444,40C91.389,40 88.889,42.25 88.889,45Z" |
|
| 24 |
+ android:fillColor="#986977"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_108sdp" |
|
| 19 |
+ android:height="@dimen/_108sdp" |
|
| 20 |
+ android:viewportWidth="108" |
|
| 21 |
+ android:viewportHeight="108"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M42,70.2C43.65,70.2 45,68.99 45,67.5V40.5C45,39.01 43.65,37.8 42,37.8C40.35,37.8 39,39.01 39,40.5V67.5C39,68.99 40.35,70.2 42,70.2ZM54,81C55.65,81 57,79.79 57,78.3V29.7C57,28.22 55.65,27 54,27C52.35,27 51,28.22 51,29.7V78.3C51,79.79 52.35,81 54,81ZM30,59.4C31.65,59.4 33,58.19 33,56.7V51.3C33,49.81 31.65,48.6 30,48.6C28.35,48.6 27,49.81 27,51.3V56.7C27,58.19 28.35,59.4 30,59.4ZM66,70.2C67.65,70.2 69,68.99 69,67.5V40.5C69,39.01 67.65,37.8 66,37.8C64.35,37.8 63,39.01 63,40.5V67.5C63,68.99 64.35,70.2 66,70.2ZM75,51.3V56.7C75,58.19 76.35,59.4 78,59.4C79.65,59.4 81,58.19 81,56.7V51.3C81,49.81 79.65,48.6 78,48.6C76.35,48.6 75,49.81 75,51.3Z" |
|
| 24 |
+ android:fillColor="#986977"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z" |
|
| 24 |
+ android:fillColor="#000000"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,28 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="200dp" |
|
| 19 |
+ android:height="200dp" |
|
| 20 |
+ android:viewportWidth="200" |
|
| 21 |
+ android:viewportHeight="200"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M100,100m-100,0a100,100 0,1 1,200 0a100,100 0,1 1,-200 0" |
|
| 24 |
+ android:fillColor="#939094"/> |
|
| 25 |
+ <path |
|
| 26 |
+ android:pathData="M100,110.526C107.114,110.526 112.814,104.884 112.814,97.895L112.857,72.632C112.857,65.642 107.114,60 100,60C92.886,60 87.143,65.642 87.143,72.632V97.895C87.143,104.884 92.886,110.526 100,110.526ZM122.714,97.895C122.714,110.526 111.829,119.368 100,119.368C88.171,119.368 77.286,110.526 77.286,97.895H70C70,112.253 81.657,124.126 95.714,126.189V140H104.286V126.189C118.343,124.168 130,112.295 130,97.895H122.714Z" |
|
| 27 |
+ android:fillColor="#313033"/> |
|
| 28 |
+</vector> |
| 0 | 29 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="200dp" |
|
| 19 |
+ android:height="200dp" |
|
| 20 |
+ android:viewportWidth="200" |
|
| 21 |
+ android:viewportHeight="200"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M100,100m-98.5,0a98.5,98.5 0,1 1,197 0a98.5,98.5 0,1 1,-197 0" |
|
| 24 |
+ android:strokeWidth="3" |
|
| 25 |
+ android:fillColor="#00000000" |
|
| 26 |
+ android:strokeColor="#EFB8C8"/> |
|
| 27 |
+ <path |
|
| 28 |
+ android:pathData="M100,100m-85,0a85,85 0,1 1,170 0a85,85 0,1 1,-170 0" |
|
| 29 |
+ android:fillColor="#EFB8C8"/> |
|
| 30 |
+ <path |
|
| 31 |
+ android:pathData="M100,110.526C107.114,110.526 112.814,104.884 112.814,97.895L112.857,72.632C112.857,65.642 107.114,60 100,60C92.886,60 87.143,65.642 87.143,72.632V97.895C87.143,104.884 92.886,110.526 100,110.526ZM122.714,97.895C122.714,110.526 111.829,119.368 100,119.368C88.171,119.368 77.286,110.526 77.286,97.895H70C70,112.253 81.657,124.126 95.714,126.189V140H104.286V126.189C118.343,124.168 130,112.295 130,97.895H122.714Z" |
|
| 32 |
+ android:fillColor="#ffffff"/> |
|
| 33 |
+</vector> |
| 0 | 34 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,29 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="18dp" |
|
| 19 |
+ android:height="20dp" |
|
| 20 |
+ android:viewportWidth="18" |
|
| 21 |
+ android:viewportHeight="20"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M17,19V17C17,15.9391 16.5786,14.9217 15.8284,14.1716C15.0783,13.4214 14.0609,13 13,13H5C3.9391,13 2.9217,13.4214 2.1716,14.1716C1.4214,14.9217 1,15.9391 1,17V19M13,5C13,7.2091 11.2091,9 9,9C6.7909,9 5,7.2091 5,5C5,2.7909 6.7909,1 9,1C11.2091,1 13,2.7909 13,5Z" |
|
| 24 |
+ android:strokeLineJoin="round" |
|
| 25 |
+ android:strokeWidth="2" |
|
| 26 |
+ android:fillColor="#00000000" |
|
| 27 |
+ android:strokeColor="@color/black_day_white_night" |
|
| 28 |
+ android:strokeLineCap="round"/> |
|
| 29 |
+</vector> |
| 0 | 30 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M8,6.82v10.36c0,0.79 0.87,1.27 1.54,0.84l8.14,-5.18c0.62,-0.39 0.62,-1.29 0,-1.69L9.54,5.98C8.87,5.55 8,6.03 8,6.82z" |
|
| 24 |
+ android:fillColor="#000000"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98 0,-0.34 -0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.09,-0.16 -0.26,-0.25 -0.44,-0.25 -0.06,0 -0.12,0.01 -0.17,0.03l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.06,-0.02 -0.12,-0.03 -0.18,-0.03 -0.17,0 -0.34,0.09 -0.43,0.25l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98 0,0.33 0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.09,0.16 0.26,0.25 0.44,0.25 0.06,0 0.12,-0.01 0.17,-0.03l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.06,0.02 0.12,0.03 0.18,0.03 0.17,0 0.34,-0.09 0.43,-0.25l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM17.45,11.27c0.04,0.31 0.05,0.52 0.05,0.73 0,0.21 -0.02,0.43 -0.05,0.73l-0.14,1.13 0.89,0.7 1.08,0.84 -0.7,1.21 -1.27,-0.51 -1.04,-0.42 -0.9,0.68c-0.43,0.32 -0.84,0.56 -1.25,0.73l-1.06,0.43 -0.16,1.13 -0.2,1.35h-1.4l-0.19,-1.35 -0.16,-1.13 -1.06,-0.43c-0.43,-0.18 -0.83,-0.41 -1.23,-0.71l-0.91,-0.7 -1.06,0.43 -1.27,0.51 -0.7,-1.21 1.08,-0.84 0.89,-0.7 -0.14,-1.13c-0.03,-0.31 -0.05,-0.54 -0.05,-0.74s0.02,-0.43 0.05,-0.73l0.14,-1.13 -0.89,-0.7 -1.08,-0.84 0.7,-1.21 1.27,0.51 1.04,0.42 0.9,-0.68c0.43,-0.32 0.84,-0.56 1.25,-0.73l1.06,-0.43 0.16,-1.13 0.2,-1.35h1.39l0.19,1.35 0.16,1.13 1.06,0.43c0.43,0.18 0.83,0.41 1.23,0.71l0.91,0.7 1.06,-0.43 1.27,-0.51 0.7,1.21 -1.07,0.85 -0.89,0.7 0.14,1.13zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z" |
|
| 24 |
+ android:fillColor="#000000"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,25 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="@dimen/_24sdp" |
|
| 19 |
+ android:height="@dimen/_24sdp" |
|
| 20 |
+ android:viewportWidth="24" |
|
| 21 |
+ android:viewportHeight="24"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92s2.92,-1.31 2.92,-2.92 -1.31,-2.92 -2.92,-2.92z" |
|
| 24 |
+ android:fillColor="#000000"/> |
|
| 25 |
+</vector> |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,202 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="862.70325dp" |
|
| 19 |
+ android:height="644.78595dp" |
|
| 20 |
+ android:viewportWidth="862.70325" |
|
| 21 |
+ android:viewportHeight="644.78595"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M629.943,612.644l-17.166,0l-8.169,-66.209l25.335,0l0,66.209z" |
|
| 24 |
+ android:fillColor="#9e616a"/> |
|
| 25 |
+ <path |
|
| 26 |
+ android:pathData="M639.003,642.385L626.693,642.385l-2.197,-11.622 -5.628,11.622L586.219,642.385A7.339,7.339 0,0 1,582.049 629.006l26.072,-18.007v-11.75l27.424,1.637Z" |
|
| 27 |
+ android:fillColor="#2f2e41"/> |
|
| 28 |
+ <path |
|
| 29 |
+ android:pathData="M731.923,590.981l-13.775,10.243l-46.063,-48.255l20.33,-15.118l39.508,53.13z" |
|
| 30 |
+ android:fillColor="#9e616a"/> |
|
| 31 |
+ <path |
|
| 32 |
+ android:pathData="M756.94,609.441 L747.062,616.786l-8.698,-8.015 2.419,12.684 -26.199,19.482a7.339,7.339 0,0 1,-11.33 -8.247l10.177,-30.007 -7.011,-9.428 22.983,-15.051Z" |
|
| 33 |
+ android:fillColor="#2f2e41"/> |
|
| 34 |
+ <path |
|
| 35 |
+ android:pathData="M649.927,271.04s32.569,28.138 17.542,108.352l-18.345,78.597 59.829,99.256 -19.077,23.208 -77.78,-107.433 -28.185,-66.114L576.003,289.236Z" |
|
| 36 |
+ android:fillColor="#2f2e41"/> |
|
| 37 |
+ <path |
|
| 38 |
+ android:pathData="M599.447,425.746l-1.959,30.338l5.995,129.281l28.209,-4.913l5.391,-92.046l-37.636,-62.66z" |
|
| 39 |
+ android:fillColor="#2f2e41"/> |
|
| 40 |
+ <path |
|
| 41 |
+ android:pathData="M237.445,628.211l15.351,-0.001l7.302,-59.209l-22.655,0.001l0.002,59.209z" |
|
| 42 |
+ android:fillColor="#ffb6b6"/> |
|
| 43 |
+ <path |
|
| 44 |
+ android:pathData="M233.53,623.199l4.321,-0 16.869,-6.86 9.041,6.859L263.762,623.198A19.266,19.266 0,0 1,283.027 642.463v0.626l-49.497,0.002Z" |
|
| 45 |
+ android:fillColor="#2f2e41"/> |
|
| 46 |
+ <path |
|
| 47 |
+ android:pathData="M296.932,618.538l14.973,3.38l20.166,-56.146l-22.099,-4.99l-13.04,57.756z" |
|
| 48 |
+ android:fillColor="#ffb6b6"/> |
|
| 49 |
+ <path |
|
| 50 |
+ android:pathData="M294.216,612.786l4.215,0.952 17.966,-2.976 7.308,8.682 0.001,0a19.266,19.266 0,0 1,14.549 23.036l-0.138,0.611L289.835,632.19Z" |
|
| 51 |
+ android:fillColor="#2f2e41"/> |
|
| 52 |
+ <path |
|
| 53 |
+ android:pathData="M218.003,266.236c-7.197,21.706 -6.436,45.268 1.73,70.556l3.491,142.378S218.023,572.539 234.806,605.395h24.34l12.051,-134.751 1.513,-90.446 52.182,76.306L291.656,603.192l29.957,2.678 53.934,-159.191L309.003,292.236Z" |
|
| 54 |
+ android:fillColor="#2f2e41"/> |
|
| 55 |
+ <path |
|
| 56 |
+ android:pathData="M498.698,204.408c18.617,-16.777 46.309,-25.212 69.537,-15.805a115.466,115.466 0,0 0,-51.888 59.935c-3.698,9.838 -6.786,21.166 -15.882,26.433 -5.659,3.278 -12.7,3.438 -19.046,1.856 -6.346,-1.582 -12.162,-4.754 -17.899,-7.894l-1.632,-0.037C469.216,244.93 480.08,221.184 498.698,204.408Z" |
|
| 57 |
+ android:fillColor="#e6e6e6"/> |
|
| 58 |
+ <path |
|
| 59 |
+ android:pathData="M568.105,189.112A98.692,98.692 0,0 0,513.199 215.043a42.5,42.5 0,0 0,-8.345 10.377,24.376 24.376,0 0,0 -2.818,12.516c0.101,4.058 0.673,8.198 -0.214,12.21a14.925,14.925 0,0 1,-7.425 9.689c-4.546,2.613 -9.759,3.437 -14.886,4.065 -5.692,0.698 -11.615,1.332 -16.542,4.525 -0.597,0.387 -1.162,-0.562 -0.566,-0.948 8.572,-5.555 19.42,-3.533 28.637,-7.241 4.301,-1.73 8.107,-4.766 9.454,-9.357 1.178,-4.015 0.591,-8.284 0.454,-12.392a26.011,26.011 0,0 1,2.299 -12.34,39.29 39.29,0 0,1 7.916,-10.659 95.749,95.749 0,0 1,24.333 -17.42A100.443,100.443 0,0 1,568.095 188.008c0.703,-0.091 0.709,1.015 0.01,1.105Z" |
|
| 60 |
+ android:fillColor="#fff"/> |
|
| 61 |
+ <path |
|
| 62 |
+ android:pathData="M517.799,210.184a14.807,14.807 0,0 1,1.632 -19.104c0.506,-0.499 1.305,0.265 0.798,0.764a13.711,13.711 0,0 0,-1.482 17.774c0.415,0.577 -0.536,1.14 -0.948,0.566Z" |
|
| 63 |
+ android:fillColor="#fff"/> |
|
| 64 |
+ <path |
|
| 65 |
+ android:pathData="M501.714,235.884a28.539,28.539 0,0 0,20.394 -4.083c0.598,-0.385 1.164,0.564 0.566,0.948a29.685,29.685 0,0 1,-21.23 4.206c-0.701,-0.126 -0.427,-1.197 0.27,-1.071Z" |
|
| 66 |
+ android:fillColor="#fff"/> |
|
| 67 |
+ <path |
|
| 68 |
+ android:pathData="M545.798,194.341a8.381,8.381 0,0 0,6.269 4.894c0.702,0.117 0.427,1.188 -0.27,1.071a9.392,9.392 0,0 1,-6.947 -5.399,0.571 0.571,0 0,1 0.191,-0.757 0.555,0.555 0,0 1,0.757 0.191Z" |
|
| 69 |
+ android:fillColor="#fff"/> |
|
| 70 |
+ <path |
|
| 71 |
+ android:pathData="M593.813,269.508c-0.44,-0.061 -0.881,-0.122 -1.328,-0.176a110.379,110.379 0,0 0,-17.882 -0.908c-0.462,0.007 -0.931,0.021 -1.392,0.041a116.365,116.365 0,0 0,-41.75 9.61,113.005 113.005,0 0,0 -15.163,8.056c-6.688,4.234 -13.602,9.358 -21.078,11.085a19.386,19.386 0,0 1,-2.362 0.421l-30.889,-26.745c-0.04,-0.096 -0.086,-0.185 -0.126,-0.282l-1.282,-1.011c0.239,-0.176 0.49,-0.353 0.729,-0.528 0.138,-0.102 0.283,-0.199 0.421,-0.301 0.094,-0.066 0.189,-0.133 0.27,-0.198 0.031,-0.022 0.063,-0.044 0.088,-0.059 0.081,-0.065 0.164,-0.117 0.239,-0.176q2.103,-1.49 4.235,-2.955c0.006,-0.007 0.006,-0.007 0.019,-0.008a166.157,166.157 0,0 1,34.601 -18.599c0.367,-0.139 0.739,-0.285 1.12,-0.411a107.831,107.831 0,0 1,16.939 -4.767,95.329 95.329,0 0,1 9.553,-1.334 79.272,79.272 0,0 1,24.723 1.752c16.143,3.743 30.91,12.608 39.656,26.433C593.378,268.799 593.596,269.147 593.813,269.508Z" |
|
| 72 |
+ android:fillColor="#e6e6e6"/> |
|
| 73 |
+ <path |
|
| 74 |
+ android:pathData="M593.404,269.839a98.692,98.692 0,0 0,-59.452 -12.353A42.5,42.5 0,0 0,521.042 260.747a24.376,24.376 0,0 0,-9.785 8.297c-2.363,3.301 -4.398,6.951 -7.522,9.62a14.925,14.925 0,0 1,-11.761 3.266c-5.203,-0.651 -9.862,-3.132 -14.333,-5.717 -4.965,-2.87 -10.076,-5.93 -15.932,-6.347 -0.71,-0.051 -0.59,-1.149 0.119,-1.098 10.189,0.726 17.633,8.871 27.225,11.46 4.476,1.208 9.343,1.075 13.182,-1.779 3.358,-2.496 5.459,-6.258 7.823,-9.621a26.011,26.011 0,0 1,9.265 -8.469,39.29 39.29,0 0,1 12.738,-3.745 95.749,95.749 0,0 1,29.917 0.742,100.443 100.443,0 0,1 32.085,11.596c0.616,0.351 -0.045,1.237 -0.657,0.888Z" |
|
| 75 |
+ android:fillColor="#fff"/> |
|
| 76 |
+ <path |
|
| 77 |
+ android:pathData="M540.551,256.376a14.807,14.807 0,0 1,12.805 -14.271c0.705,-0.093 0.883,0.997 0.177,1.09a13.711,13.711 0,0 0,-11.884 13.299c-0.016,0.711 -1.114,0.588 -1.098,-0.119Z" |
|
| 78 |
+ android:fillColor="#fff"/> |
|
| 79 |
+ <path |
|
| 80 |
+ android:pathData="M512.234,267.212a28.539,28.539 0,0 0,18.742 9.018c0.709,0.053 0.59,1.151 -0.119,1.098a29.685,29.685 0,0 1,-19.483 -9.424c-0.484,-0.523 0.38,-1.212 0.861,-0.692Z" |
|
| 81 |
+ android:fillColor="#fff"/> |
|
| 82 |
+ <path |
|
| 83 |
+ android:pathData="M572.445,260.584a8.381,8.381 0,0 0,2.058 7.682c0.49,0.516 -0.374,1.205 -0.861,0.692a9.392,9.392 0,0 1,-2.296 -8.493,0.571 0.571,0 0,1 0.609,-0.49 0.555,0.555 0,0 1,0.49 0.609Z" |
|
| 84 |
+ android:fillColor="#fff"/> |
|
| 85 |
+ <path |
|
| 86 |
+ android:pathData="M51.273,627.136c-1.45,5.44 -5.26,9.97 -9.86,13.27 -0.75,0.54 -1.52,1.04 -2.3,1.51 -0.24,0.14 -0.48,0.29 -0.73,0.42q-0.405,0.24 -0.81,0.45h-21.63c-0.39,-0.79 -0.77,-1.59 -1.15,-2.38 -9.27,-19.48 -15.78,-40.5 -14.67,-61.91a79.254,79.254 0,0 1,5.17 -24.25c5.94,-15.47 16.78,-28.86 31.69,-35.6 0.37,-0.17 0.76,-0.34 1.14,-0.5 -0.12,0.43 -0.24,0.85 -0.36,1.28a110.785,110.785 0,0 0,-3.38 17.59c-0.06,0.46 -0.11,0.92 -0.15,1.39a116.054,116.054 0,0 0,3.72 42.69c0.01,0.03 0.02,0.07 0.03,0.1q1.275,4.605 2.96,9.07c0.88,2.35 1.83,4.67 2.87,6.95C48.153,606.786 53.973,616.986 51.273,627.136Z" |
|
| 87 |
+ android:fillColor="#e6e6e6"/> |
|
| 88 |
+ <path |
|
| 89 |
+ android:pathData="M38.393,518.596c-0.21,0.28 -0.42,0.55 -0.63,0.83a98.129,98.129 0,0 0,-11.12 18.76c-0.16,0.33 -0.31,0.66 -0.44,1a97.813,97.813 0,0 0,-7.82 29.24,1.49 1.49,0 0,0 -0.02,0.21c-0.25,2.36 -0.4,4.74 -0.46,7.12a42.48,42.48 0,0 0,1.43 13.24,23.769 23.769,0 0,0 5.46,9.42c0.25,0.27 0.5,0.54 0.77,0.8 0.2,0.21 0.42,0.42 0.63,0.62 2.02,1.93 4.23,3.72 6.13,5.79a21.432,21.432 0,0 1,2.35 3,14.904 14.904,0 0,1 1.6,12.1c-1.36,5.06 -4.47,9.33 -7.65,13.4 -1.59,2.04 -3.23,4.1 -4.65,6.28 -0.52,0.78 -1,1.57 -1.44,2.38h-1.26c0.42,-0.81 0.88,-1.6 1.38,-2.38 3.65,-5.75 8.84,-10.69 11.53,-17.02 1.82,-4.27 2.37,-9.11 0.07,-13.3a17.682,17.682 0,0 0,-2.43 -3.38c-1.83,-2.07 -4.02,-3.84 -6.01,-5.71 -0.5,-0.47 -0.99,-0.95 -1.46,-1.45a24.964,24.964 0,0 1,-5.64 -8.9,39.23 39.23,0 0,1 -1.94,-13.13c0,-2.84 0.15,-5.7 0.43,-8.54 0.03,-0.36 0.07,-0.73 0.11,-1.1a100.767,100.767 0,0 1,19.67 -49.23c0.2,-0.28 0.41,-0.55 0.62,-0.82C38.033,517.266 38.823,518.046 38.393,518.596Z" |
|
| 90 |
+ android:fillColor="#fff"/> |
|
| 91 |
+ <path |
|
| 92 |
+ android:pathData="M17.717,569.071a14.807,14.807 0,0 1,-12.354 -14.663,0.553 0.553,0 0,1 1.105,-0.024 13.711,13.711 0,0 0,11.52 13.616c0.701,0.114 0.427,1.185 -0.27,1.071Z" |
|
| 93 |
+ android:fillColor="#fff"/> |
|
| 94 |
+ <path |
|
| 95 |
+ android:pathData="M24.516,598.617a28.539,28.539 0,0 0,11.533 -17.308c0.151,-0.695 1.222,-0.424 1.071,0.27a29.685,29.685 0,0 1,-12.038 17.986c-0.585,0.406 -1.148,-0.544 -0.566,-0.948Z" |
|
| 96 |
+ android:fillColor="#fff"/> |
|
| 97 |
+ <path |
|
| 98 |
+ android:pathData="M26.312,538.069a8.381,8.381 0,0 0,7.893 -0.972c0.579,-0.414 1.142,0.538 0.566,0.948a9.392,9.392 0,0 1,-8.73 1.094,0.571 0.571,0 0,1 -0.4,-0.671 0.555,0.555 0,0 1,0.671 -0.4Z" |
|
| 99 |
+ android:fillColor="#fff"/> |
|
| 100 |
+ <path |
|
| 101 |
+ android:pathData="M113.413,557.266c-0.35,0.27 -0.71,0.54 -1.06,0.82a110.362,110.362 0,0 0,-13.29 12c-0.32,0.33 -0.64,0.67 -0.95,1.01l-0.01,0.01a116.347,116.347 0,0 0,-22.66 36.14l-0.03,0.09c-0.01,0.03 -0.02,0.05 -0.03,0.08a114.443,114.443 0,0 0,-5.03 16.42c-1.22,5.46 -2.22,11.31 -4.13,16.57 -0.29,0.81 -0.61,1.61 -0.95,2.38h-44.46c0.15,-0.79 0.31,-1.59 0.47,-2.38a160.302,160.302 0,0 1,10.54 -33.7c0.16,-0.36 0.32,-0.72 0.5,-1.08a108.305,108.305 0,0 1,8.61 -15.35,0.01 0.01,0 0,1 0.01,-0.01 94.956,94.956 0,0 1,5.8 -7.69,79.119 79.119,0 0,1 18.72,-16.24c0.04,-0.03 0.09,-0.05 0.13,-0.08 14.04,-8.71 30.68,-12.86 46.59,-9.27h0.01C112.603,557.076 113.003,557.166 113.413,557.266Z" |
|
| 102 |
+ android:fillColor="#e6e6e6"/> |
|
| 103 |
+ <path |
|
| 104 |
+ android:pathData="M113.363,557.796c-0.34,0.09 -0.68,0.19 -1.01,0.29a98.589,98.589 0,0 0,-20.17 8.27c-0.32,0.17 -0.64,0.35 -0.96,0.53a98.255,98.255 0,0 0,-23.79 18.59,0.035 0.035,0 0,0 -0.01,0.02c-0.08,0.08 -0.17,0.17 -0.24,0.25 -1.6,1.72 -3.14,3.51 -4.6,5.35a42.769,42.769 0,0 0,-6.82 11.43,23.674 23.674,0 0,0 -1.31,10.81c0.03,0.37 0.08,0.73 0.13,1.1 0.04,0.29 0.08,0.58 0.13,0.88 0.66,4.01 1.8,8.03 1.48,12.12a14.909,14.909 0,0 1,-6.01 10.63,23.794 23.794,0 0,1 -3.68,2.34 36.852,36.852 0,0 1,-5.77 2.38h-3.93c0.53,-0.15 1.05,-0.3 1.58,-0.45a48.212,48.212 0,0 0,5.53 -1.93,26.912 26.912,0 0,0 3,-1.48c4.02,-2.31 7.37,-5.85 8.07,-10.58 0.61,-4.14 -0.57,-8.28 -1.27,-12.33 -0.12,-0.7 -0.23,-1.39 -0.29,-2.08a24.439,24.439 0,0 1,0.85 -10.46,39.062 39.062,0 0,1 6.36,-11.66 83.355,83.355 0,0 1,5.48 -6.55q0.36,-0.405 0.75,-0.81a100.901,100.901 0,0 1,24.21 -18.73h0.01a99.288,99.288 0,0 1,21.1 -8.74h0.01c0.33,-0.1 0.67,-0.2 1,-0.29C113.883,556.516 114.043,557.606 113.363,557.796Z" |
|
| 105 |
+ android:fillColor="#fff"/> |
|
| 106 |
+ <path |
|
| 107 |
+ android:pathData="M66.468,585.645a14.807,14.807 0,0 1,-1.036 -19.146c0.432,-0.564 1.329,0.081 0.896,0.646A13.711,13.711 0,0 0,67.328 584.953c0.491,0.514 -0.372,1.203 -0.861,0.692Z" |
|
| 108 |
+ android:fillColor="#fff"/> |
|
| 109 |
+ <path |
|
| 110 |
+ android:pathData="M54.107,613.33a28.539,28.539 0,0 0,19.629 -6.876c0.539,-0.464 1.231,0.397 0.692,0.861a29.685,29.685 0,0 1,-20.441 7.113c-0.712,-0.028 -0.589,-1.126 0.119,-1.098Z" |
|
| 111 |
+ android:fillColor="#fff"/> |
|
| 112 |
+ <path |
|
| 113 |
+ android:pathData="M91.996,566.067a8.381,8.381 0,0 0,6.887 3.977c0.712,0.019 0.588,1.117 -0.119,1.098a9.392,9.392 0,0 1,-7.629 -4.382,0.571 0.571,0 0,1 0.084,-0.776 0.555,0.555 0,0 1,0.776 0.084Z" |
|
| 114 |
+ android:fillColor="#fff"/> |
|
| 115 |
+ <path |
|
| 116 |
+ android:pathData="M456.382,173.13a11.599,11.599 0,0 1,-17.767 0.838l-37.8,16.44 3.682,-21.102 35.331,-12.377a11.662,11.662 0,0 1,16.554 16.201Z" |
|
| 117 |
+ android:fillColor="#ffb8b8"/> |
|
| 118 |
+ <path |
|
| 119 |
+ android:pathData="M431.157,179.718l-87.798,39.108 -0.188,-0.067 -100.067,-35.659a32.96,32.96 0,0 1,-14.782 -42.756h0a32.924,32.924 0,0 1,46.987 -14.637l74.468,44.859 72.211,-9.359Z" |
|
| 120 |
+ android:fillColor="#e6e6e6"/> |
|
| 121 |
+ <path |
|
| 122 |
+ android:pathData="M862.703,643.596a1.186,1.186 0,0 1,-1.19 1.19h-860.29a1.19,1.19 0,0 1,0 -2.38h860.29A1.186,1.186 0,0 1,862.703 643.596Z" |
|
| 123 |
+ android:fillColor="#ccc"/> |
|
| 124 |
+ <path |
|
| 125 |
+ android:pathData="M313.344,296.797l-88.506,-14.157a16.893,16.893 0,0 1,-9.956 -23.646l4.014,-8.028 -1.559,-84.347A62.482,62.482 0,0 1,247.673 111.965l8.631,-5.161 4.362,-11.077 40.22,0.981 0.117,14.527 14.404,22.968 -0,0.095 -0.904,125.014 -3.97,12.901 6.002,15.006Z" |
|
| 126 |
+ android:fillColor="#e6e6e6"/> |
|
| 127 |
+ <path |
|
| 128 |
+ android:pathData="M284.459,45.41m-36.544,0a36.544,36.544 0,1 1,73.088 0a36.544,36.544 0,1 1,-73.088 0" |
|
| 129 |
+ android:fillColor="#ffb8b8"/> |
|
| 130 |
+ <path |
|
| 131 |
+ android:pathData="M246.405,53.376c-1.09,-4.592 -0.59,-11.053 0.026,-15.677 1.615,-12.121 8.346,-23.645 18.573,-30.47a13.38,13.38 0,0 1,6.665 -2.648c2.419,-0.101 5.042,1.194 5.785,3.499a11.993,11.993 0,0 1,6.766 -6.709,21.135 21.135,0 0,1 9.631,-1.297 35.197,35.197 0,0 1,29.363 20.989c0.976,2.319 3.702,-6.246 4.939,-4.055a9.741,9.741 0,0 0,5.524 4.853c2.423,0.676 3.408,10.66 4.361,8.332a11.098,11.098 0,0 1,-10.611 15.475c-2.466,-0.092 -4.825,-0.999 -7.262,-1.39 -8.715,-1.396 -17.96,4.923 -19.823,13.551a23.987,23.987 0,0 0,-3.156 -7.021,8.119 8.119,0 0,0 -6.513,-3.579c-2.48,0.093 -4.659,1.714 -6.268,3.603s-2.817,4.093 -4.438,5.972c-4.755,5.513 -11.187,18.37 -17.965,17.432C256.655,73.496 247.894,59.646 246.405,53.376Z" |
|
| 132 |
+ android:fillColor="#2f2e41"/> |
|
| 133 |
+ <path |
|
| 134 |
+ android:pathData="M505.364,214.541a7.133,7.133 0,0 0,-4.807 -7.854l-98.413,-32.777a7.132,7.132 0,0 0,-2.933 -0.337l-24.667,2.333 -14.154,1.343 -26.119,2.468a7.155,7.155 0,0 0,-6.384 5.99l-13.261,82.838a7.186,7.186 0,0 0,4.484 7.796l99.44,38.384a6.947,6.947 0,0 0,1.446 0.388,7.136 7.136,0 0,0 2.176,0.016l64.255,-9.523a7.121,7.121 0,0 0,6.023 -5.999Z" |
|
| 135 |
+ android:fillColor="#fff"/> |
|
| 136 |
+ <path |
|
| 137 |
+ android:pathData="M321.365,270.503l99.44,38.382a0.897,0.897 0,0 0,0.457 0.054l64.247,-9.522a0.883,0.883 0,0 0,0.755 -0.752l12.92,-85.067a0.905,0.905 0,0 0,-0.599 -0.982l-0.662,-0.224 -97.758,-32.546a0.678,0.678 0,0 0,-0.137 -0.033,0.887 0.887,0 0,0 -0.23,-0.012l-60.164,5.693 -4.774,0.448a0.903,0.903 0,0 0,-0.795 0.748l-13.259,82.834A0.897,0.897 0,0 0,321.365 270.503Z" |
|
| 138 |
+ android:fillColor="#986977"/> |
|
| 139 |
+ <path |
|
| 140 |
+ android:pathData="M339.634,185.495l60.164,-5.693a0.887,0.887 0,0 1,0.23 0.012,0.678 0.678,0 0,1 0.137,0.033l97.758,32.546 -25.787,2.73 -9.65,1.017 -27.46,2.901a1.939,1.939 0,0 1,-0.241 -0.003c-0.049,-0.015 -0.098,-0.029 -0.156,-0.045Z" |
|
| 141 |
+ android:fillColor="#2f2e41"/> |
|
| 142 |
+ <path |
|
| 143 |
+ android:pathData="M319.109,276.345l99.44,38.382a6.722,6.722 0,0 0,1.451 0.38,7.224 7.224,0 0,0 2.177,0.027l64.247,-9.522a7.135,7.135 0,0 0,6.028 -6.004l12.91,-85.068a7.19,7.19 0,0 0,-0.418 -3.717c-0.065,-0.157 -0.131,-0.314 -0.207,-0.462a6.99,6.99 0,0 0,-2.264 -2.698,7.138 7.138,0 0,0 -1.916,-0.977l-0.117,-0.041 -98.292,-32.738a8.955,8.955 0,0 0,-1.227 -0.298,7.086 7.086,0 0,0 -1.715,-0.033l-24.663,2.325 -14.153,1.35L334.269,179.719a7.092,7.092 0,0 0,-3.019 0.997,1.329 1.329,0 0,0 -0.202,0.121 1.192,1.192 0,0 0,-0.13 0.098,7.148 7.148,0 0,0 -3.027,4.764l-13.27,82.843A7.194,7.194 0,0 0,319.109 276.345ZM329.651,185.988a5.3,5.3 0,0 1,1.27 -2.671,4.651 4.651,0 0,1 0.676,-0.659 5.317,5.317 0,0 1,2.324 -1.084,4.059 4.059,0 0,1 0.509,-0.072l43.985,-4.155 20.965,-1.995c0.142,-0.017 0.273,-0.014 0.404,-0.022a5.007,5.007 0,0 1,0.948 0.07,4.145 4.145,0 0,1 0.845,0.201l98.408,32.779c0.078,0.028 0.146,0.054 0.223,0.082a5.218,5.218 0,0 1,2.273 1.654,5.259 5.259,0 0,1 1.121,4.145l-12.921,85.077a5.349,5.349 0,0 1,-4.509 4.502l-64.257,9.521a5.413,5.413 0,0 1,-2.723 -0.31l-99.441,-38.372a5.402,5.402 0,0 1,-3.359 -5.846Z" |
|
| 144 |
+ android:fillColor="#3f3d56"/> |
|
| 145 |
+ <path |
|
| 146 |
+ android:pathData="M330.704,181.387a0.877,0.877 0,0 1,0.268 -0.386,1.051 1.051,0 0,1 0.129,-0.088c0.042,-0.016 0.084,-0.042 0.126,-0.058a0.873,0.873 0,0 1,0.624 -0.011l2.07,0.73 101.116,35.669 23.665,-2.5 13.243,-1.397 28.029,-2.967 2.506,-0.263 0.487,-0.054a0.904,0.904 0,0 1,0.952 0.654,0.739 0.739,0 0,1 0.026,0.143 0.893,0.893 0,0 1,-0.55 0.922,0.988 0.988,0 0,1 -0.248,0.067l-3.409,0.357 -27.603,2.918 -9.65,1.017 -27.46,2.901a1.939,1.939 0,0 1,-0.241 -0.003c-0.049,-0.015 -0.098,-0.029 -0.156,-0.045L331.597,182.658l-0.35,-0.124a0.67,0.67 0,0 1,-0.219 -0.121A0.91,0.91 0,0 1,330.704 181.387Z" |
|
| 147 |
+ android:fillColor="#3f3d56"/> |
|
| 148 |
+ <path |
|
| 149 |
+ android:pathData="M420.271,315.367a0.894,0.894 0,0 1,-0.743 -1.016l14.517,-96.334a0.894,0.894 0,0 1,1.017 -0.751l0.008,0.001a0.894,0.894 0,0 1,0.743 1.016l-14.517,96.334a0.894,0.894 0,0 1,-1.017 0.751Z" |
|
| 150 |
+ android:fillColor="#3f3d56"/> |
|
| 151 |
+ <path |
|
| 152 |
+ android:pathData="M457.068,309.256l-9.655,1.019 11.293,-95.535s12.895,-2.335 13.24,-1.398C472.158,213.901 457.16,308.644 457.068,309.256Z" |
|
| 153 |
+ android:fillColor="#3f3d56"/> |
|
| 154 |
+ <path |
|
| 155 |
+ android:pathData="M331.25,182.533l-0.26,43.567l77.126,29.388l27.697,-37.204l-104.563,-35.751z" |
|
| 156 |
+ android:fillColor="#3f3d56"/> |
|
| 157 |
+ <path |
|
| 158 |
+ android:pathData="M502.483,210.118a5.301,5.301 0,0 0,-2.497 -1.737l-98.406,-32.778a5.106,5.106 0,0 0,-0.848 -0.207,5.009 5.009,0 0,0 -0.951,-0.071l0.16,-0.997 0.985,-0.713 23.368,-16.919 78.041,23.917 0.135,27.052Z" |
|
| 159 |
+ android:fillColor="#3f3d56"/> |
|
| 160 |
+ <path |
|
| 161 |
+ android:pathData="M335.181,252.473a1.513,1.513 0,0 1,0.326 0.068l30.194,9.917a1.5,1.5 0,0 1,-0.936 2.851l-30.194,-9.917a1.5,1.5 0,0 1,0.61 -2.919Z" |
|
| 162 |
+ android:fillColor="#fff"/> |
|
| 163 |
+ <path |
|
| 164 |
+ android:pathData="M457.003,423.236m-12,0a12,12 0,1 1,24 0a12,12 0,1 1,-24 0" |
|
| 165 |
+ android:fillColor="#f2f2f2"/> |
|
| 166 |
+ <path |
|
| 167 |
+ android:pathData="M151.003,467.236m-12,0a12,12 0,1 1,24 0a12,12 0,1 1,-24 0" |
|
| 168 |
+ android:fillColor="#f2f2f2"/> |
|
| 169 |
+ <path |
|
| 170 |
+ android:pathData="M401.003,70.236m-12,0a12,12 0,1 1,24 0a12,12 0,1 1,-24 0" |
|
| 171 |
+ android:fillColor="#f2f2f2"/> |
|
| 172 |
+ <path |
|
| 173 |
+ android:pathData="M420.692,270.121A11.599,11.599 0,0 1,404.785 262.164L363.773,258.021l13.53,-16.606 36.871,6.481a11.662,11.662 0,0 1,6.518 22.226Z" |
|
| 174 |
+ android:fillColor="#ffb8b8"/> |
|
| 175 |
+ <path |
|
| 176 |
+ android:pathData="M395.467,263.534l-95.708,-8.818 -0.131,-0.151L229.776,174.528a32.96,32.96 0,0 1,8.013 -44.523h0a32.924,32.924 0,0 1,48.144 10.209l43.022,75.544 67.565,27.147Z" |
|
| 177 |
+ android:fillColor="#e6e6e6"/> |
|
| 178 |
+ <path |
|
| 179 |
+ android:pathData="M635.69,109.617c-2.377,-17.434 -5.358,-36.152 -17.654,-48.737a41.35,41.35 0,0 0,-59.744 0.618c-8.951,9.549 -12.904,22.957 -13.265,36.04s2.552,26.021 5.784,38.703a119.29,119.29 0,0 0,49.786 -9.799c3.926,-1.704 7.789,-3.631 11.937,-4.686 4.148,-1.056 7.105,1.601 10.963,3.453l2.118,-4.055c1.734,3.227 7.102,2.27 9.05,-0.832C636.612,117.219 636.185,113.246 635.69,109.617Z" |
|
| 180 |
+ android:fillColor="#2f2e41"/> |
|
| 181 |
+ <path |
|
| 182 |
+ android:pathData="M567.884,206.925l-69.876,1.494a11.055,11.055 0,1 0,-4.94 15.574c9.268,0.527 81.772,10.817 86.097,4.185 4.39,-6.731 27.824,-30.486 27.824,-30.486l-18.013,-25.644Z" |
|
| 183 |
+ android:fillColor="#9e616a"/> |
|
| 184 |
+ <path |
|
| 185 |
+ android:pathData="M584.911,94.035m-32.83,0a32.83,32.83 0,1 1,65.66 0a32.83,32.83 0,1 1,-65.66 0" |
|
| 186 |
+ android:fillColor="#9e616a"/> |
|
| 187 |
+ <path |
|
| 188 |
+ android:pathData="M430.713,171.577" |
|
| 189 |
+ android:fillColor="#986977"/> |
|
| 190 |
+ <path |
|
| 191 |
+ android:pathData="M637.494,157.204c-3.869,-7.7 -5.749,-17.212 -13.997,-19.708 -5.57,-1.686 -28.097,0.84 -33.173,3.686 -8.444,4.733 -0.792,13.602 -5.773,21.902 -5.415,9.023 -20.132,27.13 -25.547,36.152 -3.723,6.203 8.817,24.409 6.804,31.358 -2.013,6.948 -2.11,14.747 1.32,21.117 3.069,5.701 -1.371,10.745 1.715,16.437 3.21,5.92 7.148,28.053 4.161,34.088l-2,6c19.847,1.166 36.535,-22.544 56.258,-25.042 4.899,-0.62 9.986,-1.431 14.023,-4.274 5.946,-4.189 8.297,-11.789 9.766,-18.913A159.326,159.326 0,0 0,637.494 157.204Z" |
|
| 192 |
+ android:fillColor="#3f3d56"/> |
|
| 193 |
+ <path |
|
| 194 |
+ android:pathData="M667.25,238.505c-2.764,-7.546 -7.769,-40.537 -7.769,-40.537l-31.324,-0.918 15.314,37.772 -41.79,58.503s0.077,0.129 0.218,0.358a11.052,11.052 0,1 0,9.27 11.745,0.763 0.763,0 0,0 0.958,-0.164C616.776,299.428 670.014,246.051 667.25,238.505Z" |
|
| 195 |
+ android:fillColor="#9e616a"/> |
|
| 196 |
+ <path |
|
| 197 |
+ android:pathData="M670.434,217.67c-2.875,-12.135 -5.772,-24.335 -10.619,-35.826s-11.787,-22.343 -21.547,-30.105c-3.12,-2.482 -6.609,-4.672 -10.521,-5.444 -3.911,-0.772 -8.32,0.092 -11.067,2.981 -4.396,4.624 -3.073,12.045 -1.461,18.218Q622.352,194.795 629.483,222.096q20.594,-2.183 41.188,-4.366Z" |
|
| 198 |
+ android:fillColor="#3f3d56"/> |
|
| 199 |
+ <path |
|
| 200 |
+ android:pathData="M625.139,98.589c-1.209,-7.942 -2.472,-15.95 -5.312,-23.429 -2.84,-7.478 -7.419,-14.482 -13.986,-18.719 -10.399,-6.707 -23.862,-5.414 -35.521,-1.555 -9.016,2.984 -17.818,7.519 -24.176,14.809 -6.358,7.291 -9.93,17.694 -7.564,27.227q18.655,-4.407 37.309,-8.815l-1.361,0.962a30.038,30.038 0,0 1,16.031 20.893,31.122 31.122,0 0,1 -6.566,25.848q12.722,-4.513 25.445,-9.026c5.235,-1.857 10.838,-3.997 13.943,-8.76C626.979,112.5 626.143,105.18 625.139,98.589Z" |
|
| 201 |
+ android:fillColor="#2f2e41"/> |
|
| 202 |
+</vector> |
| 0 | 203 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,95 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ android:width="797.5dp" |
|
| 19 |
+ android:height="834.5dp" |
|
| 20 |
+ android:viewportWidth="797.5" |
|
| 21 |
+ android:viewportHeight="834.5"> |
|
| 22 |
+ <path |
|
| 23 |
+ android:pathData="M0,780a308.5,54.5 0,1 0,617 0a308.5,54.5 0,1 0,-617 0z" |
|
| 24 |
+ android:fillColor="#3f3d56"/> |
|
| 25 |
+ <path |
|
| 26 |
+ android:pathData="M496,301.5m-301.5,0a301.5,301.5 0,1 1,603 0a301.5,301.5 0,1 1,-603 0" |
|
| 27 |
+ android:fillColor="#3f3d56"/> |
|
| 28 |
+ <path |
|
| 29 |
+ android:fillColor="#FF000000" |
|
| 30 |
+ android:pathData="M496,301.5m-248.898,0a248.898,248.898 0,1 1,497.796 0a248.898,248.898 0,1 1,-497.796 0" |
|
| 31 |
+ android:strokeAlpha="0.05" |
|
| 32 |
+ android:fillAlpha="0.05"/> |
|
| 33 |
+ <path |
|
| 34 |
+ android:fillColor="#FF000000" |
|
| 35 |
+ android:pathData="M496,301.5m-203.994,0a203.994,203.994 0,1 1,407.987 0a203.994,203.994 0,1 1,-407.987 0" |
|
| 36 |
+ android:strokeAlpha="0.05" |
|
| 37 |
+ android:fillAlpha="0.05"/> |
|
| 38 |
+ <path |
|
| 39 |
+ android:fillColor="#FF000000" |
|
| 40 |
+ android:pathData="M496,301.5m-146.26,0a146.26,146.26 0,1 1,292.519 0a146.26,146.26 0,1 1,-292.519 0" |
|
| 41 |
+ android:strokeAlpha="0.05" |
|
| 42 |
+ android:fillAlpha="0.05"/> |
|
| 43 |
+ <path |
|
| 44 |
+ android:pathData="M197.17,328.482s-23.704,66.722 -13.169,90.426 27.216,46.53 27.216,46.53S205.072,332.872 197.17,328.482Z" |
|
| 45 |
+ android:fillColor="#d0cde1"/> |
|
| 46 |
+ <path |
|
| 47 |
+ android:fillColor="#FF000000" |
|
| 48 |
+ android:pathData="M197.17,328.482s-23.704,66.722 -13.169,90.426 27.216,46.53 27.216,46.53S205.072,332.872 197.17,328.482Z" |
|
| 49 |
+ android:strokeAlpha="0.1" |
|
| 50 |
+ android:fillAlpha="0.1"/> |
|
| 51 |
+ <path |
|
| 52 |
+ android:pathData="M213.851,482.997s-1.756,16.681 -2.634,17.558 0.878,2.634 0,5.268 -1.756,6.145 0,7.023 -9.657,78.135 -9.657,78.135 -28.094,36.873 -16.681,94.816l3.512,58.821s27.216,1.756 27.216,-7.901c0,0 -1.756,-11.413 -1.756,-16.681s4.39,-5.268 1.756,-7.901 -2.634,-4.39 -2.634,-4.39 4.39,-3.512 3.512,-4.39 7.901,-63.21 7.901,-63.21 9.657,-9.657 9.657,-14.925v-5.268s4.39,-11.413 4.39,-12.291 23.704,-54.431 23.704,-54.431l9.657,38.629 10.535,55.309s5.268,50.042 15.803,69.356c0,0 18.436,63.211 18.436,61.455s30.727,-6.145 29.849,-14.047 -18.436,-118.52 -18.436,-118.52L332.371,481.241Z" |
|
| 53 |
+ android:fillColor="#2f2e41"/> |
|
| 54 |
+ <path |
|
| 55 |
+ android:pathData="M190.147,740.228s-23.704,46.53 -7.901,48.286 21.948,1.756 28.971,-5.268c3.84,-3.84 11.615,-8.991 17.876,-12.873a23.117,23.117 0,0 0,10.969 -21.982c-0.463,-4.295 -2.068,-7.834 -6.019,-8.164 -10.535,-0.878 -22.826,-10.535 -22.826,-10.535Z" |
|
| 56 |
+ android:fillColor="#2f2e41"/> |
|
| 57 |
+ <path |
|
| 58 |
+ android:pathData="M320.958,774.467s-23.704,46.53 -7.901,48.286 21.948,1.756 28.971,-5.268c3.84,-3.84 11.615,-8.991 17.876,-12.873a23.117,23.117 0,0 0,10.969 -21.982c-0.463,-4.295 -2.068,-7.834 -6.019,-8.164 -10.535,-0.878 -22.826,-10.535 -22.826,-10.535Z" |
|
| 59 |
+ android:fillColor="#2f2e41"/> |
|
| 60 |
+ <path |
|
| 61 |
+ android:pathData="M295.905,215.433m-36.905,0a36.905,36.905 0,1 1,73.809 0a36.905,36.905 0,1 1,-73.809 0" |
|
| 62 |
+ android:fillColor="#ffb8b8"/> |
|
| 63 |
+ <path |
|
| 64 |
+ android:pathData="M272.18,227.558S245.82,276.062 243.711,276.062 291.16,291.878 291.16,291.878s13.707,-46.394 15.816,-50.612Z" |
|
| 65 |
+ android:fillColor="#ffb8b8"/> |
|
| 66 |
+ <path |
|
| 67 |
+ android:pathData="M312.617,280.635s-52.675,-28.971 -57.943,-28.094 -61.455,50.042 -60.577,70.234 7.901,53.553 7.901,53.553 2.634,93.06 7.901,93.938 -0.878,16.681 0.878,16.681 122.909,0 123.787,-2.634S312.617,280.635 312.617,280.635Z" |
|
| 68 |
+ android:fillColor="#d0cde1"/> |
|
| 69 |
+ <path |
|
| 70 |
+ android:pathData="M342.028,489.142s16.681,50.92 2.634,49.164 -20.192,-43.896 -20.192,-43.896Z" |
|
| 71 |
+ android:fillColor="#ffb8b8"/> |
|
| 72 |
+ <path |
|
| 73 |
+ android:pathData="M297.254,277.563s-32.483,7.023 -27.216,50.92 14.925,87.792 14.925,87.792l32.483,71.112 3.512,13.169 23.704,-6.145L327.103,392.571s-6.145,-108.863 -14.047,-112.374A34,34 0,0 0,297.254 277.563Z" |
|
| 74 |
+ android:fillColor="#d0cde1"/> |
|
| 75 |
+ <path |
|
| 76 |
+ android:fillColor="#FF000000" |
|
| 77 |
+ android:pathData="M277.5,414.958l40.385,71.989l-34.025,-75.857l-6.36,3.868z" |
|
| 78 |
+ android:strokeAlpha="0.1" |
|
| 79 |
+ android:fillAlpha="0.1"/> |
|
| 80 |
+ <path |
|
| 81 |
+ android:pathData="M332.646,204.566l0.122,-2.82 5.61,1.396a6.27,6.27 0,0 0,-2.514 -4.615l5.976,-0.334a64.477,64.477 0,0 0,-43.125 -26.651c-12.926,-1.873 -27.318,0.838 -36.182,10.43 -4.299,4.653 -7.001,10.57 -8.922,16.607 -3.539,11.118 -4.26,24.372 3.12,33.409 7.501,9.185 20.602,10.984 32.406,12.121 4.153,0.4 8.506,0.772 12.355,-0.839a29.721,29.721 0,0 0,-1.654 -13.037,8.687 8.687,0 0,1 -0.879,-4.152c0.525,-3.512 5.209,-4.396 8.728,-3.922s7.75,1.2 10.062,-1.494c1.593,-1.856 1.499,-4.559 1.71,-6.996C320.032,207.035 332.586,205.957 332.646,204.566Z" |
|
| 82 |
+ android:fillColor="#2f2e41"/> |
|
| 83 |
+ <path |
|
| 84 |
+ android:pathData="M559,744.5m-43,0a43,43 0,1 1,86 0a43,43 0,1 1,-86 0" |
|
| 85 |
+ android:fillColor="#986977"/> |
|
| 86 |
+ <path |
|
| 87 |
+ android:pathData="M54,729.5m-43,0a43,43 0,1 1,86 0a43,43 0,1 1,-86 0" |
|
| 88 |
+ android:fillColor="#986977"/> |
|
| 89 |
+ <path |
|
| 90 |
+ android:pathData="M54,672.5m-31,0a31,31 0,1 1,62 0a31,31 0,1 1,-62 0" |
|
| 91 |
+ android:fillColor="#986977"/> |
|
| 92 |
+ <path |
|
| 93 |
+ android:pathData="M54,624.5m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0" |
|
| 94 |
+ android:fillColor="#986977"/> |
|
| 95 |
+</vector> |
| 26 | 122 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,27 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 17 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 18 |
+ android:id="@+id/nav_host_fragment" |
|
| 19 |
+ android:name="androidx.navigation.fragment.NavHostFragment" |
|
| 20 |
+ android:layout_width="match_parent" |
|
| 21 |
+ android:layout_height="match_parent" |
|
| 22 |
+ app:defaultNavHost="true" |
|
| 23 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 24 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 25 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 26 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 27 |
+ app:navGraph="@navigation/navigation" /> |
|
| 0 | 28 |
\ No newline at end of file |
| 1 | 29 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,121 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<layout xmlns:tools="http://schemas.android.com/tools" |
|
| 18 |
+ xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 19 |
+ xmlns:app="http://schemas.android.com/apk/res-auto"> |
|
| 20 |
+ |
|
| 21 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 22 |
+ android:id="@+id/bottom_sheet_dialog" |
|
| 23 |
+ android:layout_width="match_parent" |
|
| 24 |
+ android:layout_height="wrap_content" |
|
| 25 |
+ android:background="@color/other_fragment_background" |
|
| 26 |
+ android:backgroundTint="#27FFFFFF" |
|
| 27 |
+ android:backgroundTintMode="screen" |
|
| 28 |
+ app:behavior_hideable="true" |
|
| 29 |
+ app:behavior_peekHeight="@dimen/_32sdp" |
|
| 30 |
+ app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"> |
|
| 31 |
+ |
|
| 32 |
+ <androidx.appcompat.widget.LinearLayoutCompat |
|
| 33 |
+ android:id="@+id/linearLayoutCompat" |
|
| 34 |
+ android:layout_width="0dp" |
|
| 35 |
+ android:layout_height="wrap_content" |
|
| 36 |
+ android:background="@color/other_fragment_background" |
|
| 37 |
+ android:orientation="horizontal" |
|
| 38 |
+ android:paddingStart="@dimen/_16sdp" |
|
| 39 |
+ android:paddingTop="@dimen/_8sdp" |
|
| 40 |
+ android:paddingEnd="@dimen/_16sdp" |
|
| 41 |
+ android:paddingBottom="@dimen/_8sdp" |
|
| 42 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 43 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 44 |
+ app:layout_constraintTop_toTopOf="parent"> |
|
| 45 |
+ |
|
| 46 |
+ <androidx.appcompat.widget.AppCompatImageView |
|
| 47 |
+ android:layout_width="wrap_content" |
|
| 48 |
+ android:layout_height="wrap_content" |
|
| 49 |
+ android:tint="@color/black_day_white_night" |
|
| 50 |
+ app:srcCompat="@drawable/ic_mic_black_24dp" /> |
|
| 51 |
+ |
|
| 52 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 53 |
+ android:layout_width="wrap_content" |
|
| 54 |
+ android:layout_height="wrap_content" |
|
| 55 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 56 |
+ android:layout_weight="3" |
|
| 57 |
+ android:text="@string/record_player" |
|
| 58 |
+ android:textColor="@color/black_day_white_night" |
|
| 59 |
+ android:textSize="@dimen/_16ssp" |
|
| 60 |
+ android:fontFamily="@font/open_sans_bold"/> |
|
| 61 |
+ |
|
| 62 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 63 |
+ android:id="@+id/tv_now_playing" |
|
| 64 |
+ android:layout_width="wrap_content" |
|
| 65 |
+ android:layout_height="wrap_content" |
|
| 66 |
+ android:layout_weight="3" |
|
| 67 |
+ android:text="@string/now_playing" |
|
| 68 |
+ android:textSize="@dimen/_12ssp" |
|
| 69 |
+ android:textColor="@color/black_day_white_night" |
|
| 70 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 71 |
+ android:textAlignment="textEnd" /> |
|
| 72 |
+ |
|
| 73 |
+ </androidx.appcompat.widget.LinearLayoutCompat> |
|
| 74 |
+ |
|
| 75 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 76 |
+ android:id="@+id/tv_note_title" |
|
| 77 |
+ android:layout_width="0dp" |
|
| 78 |
+ android:layout_height="wrap_content" |
|
| 79 |
+ android:layout_marginTop="@dimen/_20sdp" |
|
| 80 |
+ android:ellipsize="end" |
|
| 81 |
+ android:maxLines="1" |
|
| 82 |
+ android:textAlignment="center" |
|
| 83 |
+ android:textSize="@dimen/_16ssp" |
|
| 84 |
+ android:textColor="@color/black_day_white_night" |
|
| 85 |
+ android:fontFamily="@font/open_sans_semi_bold" |
|
| 86 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 87 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 88 |
+ app:layout_constraintTop_toBottomOf="@+id/linearLayoutCompat" |
|
| 89 |
+ tools:text="CPE 407 - Lecture 1" /> |
|
| 90 |
+ |
|
| 91 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 92 |
+ android:id="@+id/btn_play" |
|
| 93 |
+ android:layout_width="wrap_content" |
|
| 94 |
+ android:layout_height="wrap_content" |
|
| 95 |
+ android:layout_marginTop="@dimen/_8sdp" |
|
| 96 |
+ android:background="@null" |
|
| 97 |
+ android:src="@drawable/ic_play_arrow_black_24dp" |
|
| 98 |
+ android:tint="@color/black_day_white_night" |
|
| 99 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 100 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 101 |
+ app:layout_constraintTop_toBottomOf="@+id/tv_note_title" /> |
|
| 102 |
+ |
|
| 103 |
+ <SeekBar |
|
| 104 |
+ android:id="@+id/seekbar" |
|
| 105 |
+ style="@android:style/Widget.Material.SeekBar" |
|
| 106 |
+ android:layout_width="0dp" |
|
| 107 |
+ android:layout_height="wrap_content" |
|
| 108 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 109 |
+ android:layout_marginTop="@dimen/_8sdp" |
|
| 110 |
+ android:layout_marginEnd="@dimen/_16sdp" |
|
| 111 |
+ android:layout_marginBottom="@dimen/_8sdp" |
|
| 112 |
+ android:progress="42" |
|
| 113 |
+ android:progressTint="@color/black_day_white_night" |
|
| 114 |
+ android:thumbTint="@color/black_day_white_night" |
|
| 115 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 116 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 117 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 118 |
+ app:layout_constraintTop_toBottomOf="@+id/btn_play" /> |
|
| 119 |
+ |
|
| 120 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 121 |
+</layout> |
|
| 0 | 122 |
\ No newline at end of file |
| 1 | 123 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,105 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+<layout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 17 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 18 |
+ xmlns:tools="http://schemas.android.com/tools"> |
|
| 19 |
+ |
|
| 20 |
+ <data> |
|
| 21 |
+ |
|
| 22 |
+ <variable |
|
| 23 |
+ name="note" |
|
| 24 |
+ type="com.certified.audionote.model.Note" /> |
|
| 25 |
+ |
|
| 26 |
+ <import type="com.certified.audionote.utils.UtilKt" /> |
|
| 27 |
+ </data> |
|
| 28 |
+ |
|
| 29 |
+ <androidx.coordinatorlayout.widget.CoordinatorLayout |
|
| 30 |
+ android:layout_width="match_parent" |
|
| 31 |
+ android:layout_height="wrap_content"> |
|
| 32 |
+ |
|
| 33 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 34 |
+ android:layout_width="match_parent" |
|
| 35 |
+ android:layout_height="wrap_content" |
|
| 36 |
+ android:padding="@dimen/_8sdp"> |
|
| 37 |
+ |
|
| 38 |
+ <androidx.appcompat.widget.AppCompatImageView |
|
| 39 |
+ android:id="@+id/appCompatImageView" |
|
| 40 |
+ android:layout_width="wrap_content" |
|
| 41 |
+ android:layout_height="wrap_content" |
|
| 42 |
+ android:layout_margin="@dimen/_8sdp" |
|
| 43 |
+ android:contentDescription="@string/alarm_icon" |
|
| 44 |
+ android:tint="@color/black_day_white_night" |
|
| 45 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 46 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 47 |
+ app:srcCompat="@drawable/ic_alarm_on_black_24dp" /> |
|
| 48 |
+ |
|
| 49 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 50 |
+ android:id="@+id/tv_reminder_time" |
|
| 51 |
+ android:layout_width="wrap_content" |
|
| 52 |
+ android:layout_height="wrap_content" |
|
| 53 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 54 |
+ android:fontFamily="@font/open_sans_semi_bold" |
|
| 55 |
+ android:text="@{UtilKt.formatTime(note.reminder)}"
|
|
| 56 |
+ android:textColor="@color/black_day_white_night" |
|
| 57 |
+ android:textSize="@dimen/_14ssp" |
|
| 58 |
+ app:layout_constraintStart_toEndOf="@id/appCompatImageView" |
|
| 59 |
+ app:layout_constraintTop_toTopOf="@id/appCompatImageView" |
|
| 60 |
+ tools:text="10:30 AM" /> |
|
| 61 |
+ |
|
| 62 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 63 |
+ android:id="@+id/tv_reminder_date" |
|
| 64 |
+ android:layout_width="wrap_content" |
|
| 65 |
+ android:layout_height="wrap_content" |
|
| 66 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 67 |
+ android:text="@{UtilKt.formatDateOnly(note.reminder)}"
|
|
| 68 |
+ android:textColor="@color/black_day_white_night" |
|
| 69 |
+ android:textSize="@dimen/_12ssp" |
|
| 70 |
+ app:layout_constraintStart_toStartOf="@+id/tv_reminder_time" |
|
| 71 |
+ app:layout_constraintTop_toBottomOf="@+id/tv_reminder_time" |
|
| 72 |
+ tools:text="13th Dec. 2020" /> |
|
| 73 |
+ |
|
| 74 |
+ <com.google.android.material.button.MaterialButton |
|
| 75 |
+ android:id="@+id/btn_modify_reminder" |
|
| 76 |
+ android:layout_width="0dp" |
|
| 77 |
+ android:layout_height="wrap_content" |
|
| 78 |
+ android:layout_marginStart="@dimen/_8sdp" |
|
| 79 |
+ android:layout_marginEnd="@dimen/_8sdp" |
|
| 80 |
+ android:backgroundTint="@color/edit_reminder_button_color" |
|
| 81 |
+ android:fontFamily="@font/open_sans_semi_bold" |
|
| 82 |
+ android:text="@string/modify" |
|
| 83 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 84 |
+ app:layout_constraintStart_toEndOf="@id/btn_delete_reminder" |
|
| 85 |
+ app:layout_constraintTop_toTopOf="@id/btn_delete_reminder" /> |
|
| 86 |
+ |
|
| 87 |
+ <com.google.android.material.button.MaterialButton |
|
| 88 |
+ android:id="@+id/btn_delete_reminder" |
|
| 89 |
+ style="?attr/materialButtonOutlinedStyle" |
|
| 90 |
+ android:layout_width="0dp" |
|
| 91 |
+ android:layout_height="wrap_content" |
|
| 92 |
+ android:layout_marginStart="@dimen/_8sdp" |
|
| 93 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 94 |
+ android:layout_marginEnd="@dimen/_8sdp" |
|
| 95 |
+ android:fontFamily="@font/open_sans_semi_bold" |
|
| 96 |
+ android:text="@string/delete" |
|
| 97 |
+ android:textColor="@color/edit_reminder_button_color" |
|
| 98 |
+ app:layout_constraintEnd_toStartOf="@id/btn_modify_reminder" |
|
| 99 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 100 |
+ app:layout_constraintTop_toBottomOf="@+id/appCompatImageView" |
|
| 101 |
+ app:strokeColor="@color/edit_reminder_button_color" /> |
|
| 102 |
+ |
|
| 103 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 104 |
+ </androidx.coordinatorlayout.widget.CoordinatorLayout> |
|
| 105 |
+</layout> |
|
| 0 | 106 |
\ No newline at end of file |
| 1 | 107 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,152 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<layout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 19 |
+ xmlns:tools="http://schemas.android.com/tools"> |
|
| 20 |
+ |
|
| 21 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 22 |
+ android:layout_width="match_parent" |
|
| 23 |
+ android:layout_height="match_parent" |
|
| 24 |
+ android:background="@color/fragment_background" |
|
| 25 |
+ tools:context=".ui.AboutFragment"> |
|
| 26 |
+ |
|
| 27 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 28 |
+ android:id="@+id/btn_back" |
|
| 29 |
+ app:layout_constraintBottom_toBottomOf="@+id/materialTextView" |
|
| 30 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 31 |
+ app:layout_constraintTop_toTopOf="@+id/materialTextView" |
|
| 32 |
+ android:background="@null" |
|
| 33 |
+ android:padding="@dimen/_4sdp" |
|
| 34 |
+ android:layout_marginStart="@dimen/_8sdp" |
|
| 35 |
+ android:layout_width="wrap_content" |
|
| 36 |
+ android:layout_height="wrap_content" |
|
| 37 |
+ android:layout_gravity="center" |
|
| 38 |
+ android:tint="@color/black_day_white_night" |
|
| 39 |
+ app:srcCompat="@drawable/ic_arrow_back_black_24dp" /> |
|
| 40 |
+ |
|
| 41 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 42 |
+ android:id="@+id/materialTextView" |
|
| 43 |
+ android:layout_width="wrap_content" |
|
| 44 |
+ android:layout_height="wrap_content" |
|
| 45 |
+ android:layout_marginStart="@dimen/_32sdp" |
|
| 46 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 47 |
+ android:text="@string/about" |
|
| 48 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 49 |
+ android:textSize="@dimen/_22ssp" |
|
| 50 |
+ android:textColor="@color/black_day_white_night" |
|
| 51 |
+ app:layout_constraintStart_toEndOf="@+id/btn_back" |
|
| 52 |
+ app:layout_constraintTop_toTopOf="parent" /> |
|
| 53 |
+ |
|
| 54 |
+ <androidx.constraintlayout.widget.Guideline |
|
| 55 |
+ android:id="@+id/guideline3" |
|
| 56 |
+ android:layout_width="wrap_content" |
|
| 57 |
+ android:layout_height="wrap_content" |
|
| 58 |
+ android:orientation="horizontal" |
|
| 59 |
+ app:layout_constraintGuide_percent=".2" /> |
|
| 60 |
+ |
|
| 61 |
+ <com.google.android.material.card.MaterialCardView |
|
| 62 |
+ android:id="@+id/receiver_profile_image" |
|
| 63 |
+ android:layout_width="wrap_content" |
|
| 64 |
+ android:layout_height="wrap_content" |
|
| 65 |
+ android:elevation="@dimen/_4sdp" |
|
| 66 |
+ app:cardBackgroundColor="@color/about_icon_color" |
|
| 67 |
+ app:cardCornerRadius="@dimen/_16sdp" |
|
| 68 |
+ app:cardUseCompatPadding="false" |
|
| 69 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 70 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 71 |
+ app:layout_constraintTop_toTopOf="@+id/guideline3"> |
|
| 72 |
+ |
|
| 73 |
+ <androidx.appcompat.widget.AppCompatImageView |
|
| 74 |
+ android:layout_width="wrap_content" |
|
| 75 |
+ android:layout_height="wrap_content" |
|
| 76 |
+ android:layout_margin="@dimen/_8sdp" |
|
| 77 |
+ android:src="@drawable/ic_logo_audio_note" /> |
|
| 78 |
+ |
|
| 79 |
+ </com.google.android.material.card.MaterialCardView> |
|
| 80 |
+ |
|
| 81 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 82 |
+ android:id="@+id/materialTextView4" |
|
| 83 |
+ android:layout_width="wrap_content" |
|
| 84 |
+ android:layout_height="wrap_content" |
|
| 85 |
+ android:text="@string/app_name" |
|
| 86 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 87 |
+ android:textColor="@color/black_day_white_night" |
|
| 88 |
+ android:textSize="@dimen/_14ssp" |
|
| 89 |
+ app:layout_constraintEnd_toEndOf="@+id/receiver_profile_image" |
|
| 90 |
+ app:layout_constraintStart_toStartOf="@+id/receiver_profile_image" |
|
| 91 |
+ app:layout_constraintTop_toBottomOf="@+id/receiver_profile_image" /> |
|
| 92 |
+ |
|
| 93 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 94 |
+ android:id="@+id/materialTextView5" |
|
| 95 |
+ android:layout_width="wrap_content" |
|
| 96 |
+ android:layout_height="wrap_content" |
|
| 97 |
+ android:text="@string/app_version" |
|
| 98 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 99 |
+ android:textSize="@dimen/_12ssp" |
|
| 100 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 101 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 102 |
+ app:layout_constraintTop_toBottomOf="@+id/materialTextView4" /> |
|
| 103 |
+ |
|
| 104 |
+ <com.google.android.material.card.MaterialCardView |
|
| 105 |
+ android:layout_width="0dp" |
|
| 106 |
+ android:layout_height="wrap_content" |
|
| 107 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 108 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 109 |
+ android:layout_marginEnd="@dimen/_16sdp" |
|
| 110 |
+ app:cardBackgroundColor="@color/about_icon_color" |
|
| 111 |
+ app:cardCornerRadius="@dimen/_10sdp" |
|
| 112 |
+ android:elevation="@dimen/_4sdp" |
|
| 113 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 114 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 115 |
+ app:layout_constraintTop_toBottomOf="@+id/materialTextView5"> |
|
| 116 |
+ |
|
| 117 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 118 |
+ android:layout_width="match_parent" |
|
| 119 |
+ android:layout_height="match_parent"> |
|
| 120 |
+ |
|
| 121 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 122 |
+ android:id="@+id/materialTextView7" |
|
| 123 |
+ android:layout_width="wrap_content" |
|
| 124 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 125 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 126 |
+ android:layout_height="wrap_content" |
|
| 127 |
+ android:text="@string/attributions_amp_licence" |
|
| 128 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 129 |
+ android:textSize="@dimen/_16ssp" |
|
| 130 |
+ android:textColor="@color/black_day_white_night" |
|
| 131 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 132 |
+ app:layout_constraintTop_toTopOf="parent" /> |
|
| 133 |
+ |
|
| 134 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 135 |
+ android:id="@+id/materialTextView6" |
|
| 136 |
+ android:layout_width="0dp" |
|
| 137 |
+ android:layout_height="wrap_content" |
|
| 138 |
+ android:layout_marginBottom="@dimen/_16sdp" |
|
| 139 |
+ android:text="@string/licenced_under_apache_licence_version_2_0" |
|
| 140 |
+ android:textSize="@dimen/_12ssp" |
|
| 141 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 142 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 143 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 144 |
+ app:layout_constraintStart_toStartOf="@+id/materialTextView7" |
|
| 145 |
+ app:layout_constraintTop_toBottomOf="@+id/materialTextView7" /> |
|
| 146 |
+ |
|
| 147 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 148 |
+ |
|
| 149 |
+ </com.google.android.material.card.MaterialCardView> |
|
| 150 |
+ |
|
| 151 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 152 |
+</layout> |
|
| 0 | 153 |
\ No newline at end of file |
| 1 | 154 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,256 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<layout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 19 |
+ xmlns:tools="http://schemas.android.com/tools" |
|
| 20 |
+ tools:context=".ui.AddNoteFragment"> |
|
| 21 |
+ |
|
| 22 |
+ <data> |
|
| 23 |
+ |
|
| 24 |
+ <import type="com.certified.audionote.utils.UtilKt" /> |
|
| 25 |
+ |
|
| 26 |
+ <import type="com.certified.audionote.utils.ReminderAvailableState" /> |
|
| 27 |
+ |
|
| 28 |
+ <import type="com.certified.audionote.utils.ReminderCompletionState" /> |
|
| 29 |
+ |
|
| 30 |
+ <variable |
|
| 31 |
+ name="viewModel" |
|
| 32 |
+ type="com.certified.audionote.ui.NotesViewModel" /> |
|
| 33 |
+ |
|
| 34 |
+ <variable |
|
| 35 |
+ name="reminderAvailableState" |
|
| 36 |
+ type="ReminderAvailableState" /> |
|
| 37 |
+ |
|
| 38 |
+ <variable |
|
| 39 |
+ name="reminderCompletionState" |
|
| 40 |
+ type="ReminderCompletionState" /> |
|
| 41 |
+ |
|
| 42 |
+ <variable |
|
| 43 |
+ name="note" |
|
| 44 |
+ type="com.certified.audionote.model.Note" /> |
|
| 45 |
+ </data> |
|
| 46 |
+ |
|
| 47 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 48 |
+ android:id="@+id/parent" |
|
| 49 |
+ android:layout_width="match_parent" |
|
| 50 |
+ android:layout_height="match_parent" |
|
| 51 |
+ android:background="@{note.color}">
|
|
| 52 |
+ |
|
| 53 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 54 |
+ android:id="@+id/btn_back" |
|
| 55 |
+ android:layout_width="wrap_content" |
|
| 56 |
+ android:layout_height="wrap_content" |
|
| 57 |
+ android:layout_gravity="center" |
|
| 58 |
+ android:layout_marginStart="@dimen/_8sdp" |
|
| 59 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 60 |
+ android:background="@null" |
|
| 61 |
+ android:contentDescription="@string/back_button" |
|
| 62 |
+ android:padding="@dimen/_4sdp" |
|
| 63 |
+ android:tint="@color/black_day_white_night" |
|
| 64 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 65 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 66 |
+ app:srcCompat="@drawable/ic_arrow_back_black_24dp" |
|
| 67 |
+ tools:ignore="TouchTargetSizeCheck" /> |
|
| 68 |
+ |
|
| 69 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 70 |
+ android:id="@+id/tv_title" |
|
| 71 |
+ android:layout_width="wrap_content" |
|
| 72 |
+ android:layout_height="wrap_content" |
|
| 73 |
+ android:layout_marginStart="@dimen/_32sdp" |
|
| 74 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 75 |
+ android:text="@string/new_note" |
|
| 76 |
+ android:textColor="@color/black_day_white_night" |
|
| 77 |
+ android:textSize="@dimen/_18ssp" |
|
| 78 |
+ app:layout_constraintBottom_toBottomOf="@+id/btn_back" |
|
| 79 |
+ app:layout_constraintStart_toEndOf="@+id/btn_back" |
|
| 80 |
+ app:layout_constraintTop_toTopOf="@+id/btn_back" /> |
|
| 81 |
+ |
|
| 82 |
+ <ScrollView |
|
| 83 |
+ android:id="@+id/scrollView2" |
|
| 84 |
+ android:layout_width="0dp" |
|
| 85 |
+ android:layout_height="0dp" |
|
| 86 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 87 |
+ android:layout_marginEnd="@dimen/_16sdp" |
|
| 88 |
+ android:paddingTop="@dimen/_16sdp" |
|
| 89 |
+ app:layout_constraintBottom_toTopOf="@+id/card_add_reminder" |
|
| 90 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 91 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 92 |
+ app:layout_constraintTop_toBottomOf="@+id/btn_back"> |
|
| 93 |
+ |
|
| 94 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 95 |
+ android:layout_width="match_parent" |
|
| 96 |
+ android:layout_height="wrap_content"> |
|
| 97 |
+ |
|
| 98 |
+ <com.google.android.material.textfield.TextInputEditText |
|
| 99 |
+ android:id="@+id/et_note_title" |
|
| 100 |
+ android:layout_width="0dp" |
|
| 101 |
+ android:layout_height="wrap_content" |
|
| 102 |
+ android:background="@null" |
|
| 103 |
+ android:fontFamily="@font/open_sans_semi_bold" |
|
| 104 |
+ android:gravity="start|top" |
|
| 105 |
+ android:hint="@string/note_title_required" |
|
| 106 |
+ android:inputType="textMultiLine" |
|
| 107 |
+ android:maxLength="50" |
|
| 108 |
+ android:text="@{note.title}"
|
|
| 109 |
+ android:textSize="@dimen/_16ssp" |
|
| 110 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 111 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 112 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 113 |
+ tools:ignore="TouchTargetSizeCheck,TextContrastCheck" /> |
|
| 114 |
+ |
|
| 115 |
+ <com.google.android.material.textfield.TextInputEditText |
|
| 116 |
+ android:id="@+id/et_note_description" |
|
| 117 |
+ android:layout_width="0dp" |
|
| 118 |
+ android:layout_height="0dp" |
|
| 119 |
+ android:layout_marginTop="@dimen/_10sdp" |
|
| 120 |
+ android:background="@null" |
|
| 121 |
+ android:ems="10" |
|
| 122 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 123 |
+ android:gravity="start|top" |
|
| 124 |
+ android:hint="@string/description" |
|
| 125 |
+ android:inputType="textMultiLine" |
|
| 126 |
+ android:text="@{note.description}"
|
|
| 127 |
+ android:textSize="@dimen/_12ssp" |
|
| 128 |
+ app:layout_constraintBottom_toTopOf="@+id/guideline2" |
|
| 129 |
+ app:layout_constraintEnd_toEndOf="@+id/et_note_title" |
|
| 130 |
+ app:layout_constraintHorizontal_bias="1.0" |
|
| 131 |
+ app:layout_constraintStart_toStartOf="@+id/et_note_title" |
|
| 132 |
+ app:layout_constraintTop_toBottomOf="@+id/et_note_title" |
|
| 133 |
+ tools:ignore="TextContrastCheck" /> |
|
| 134 |
+ |
|
| 135 |
+ <androidx.constraintlayout.widget.Guideline |
|
| 136 |
+ android:id="@+id/guideline2" |
|
| 137 |
+ android:layout_width="wrap_content" |
|
| 138 |
+ android:layout_height="wrap_content" |
|
| 139 |
+ android:orientation="horizontal" |
|
| 140 |
+ app:layout_constraintGuide_percent=".4" /> |
|
| 141 |
+ |
|
| 142 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 143 |
+ android:id="@+id/tv_timer" |
|
| 144 |
+ android:layout_width="wrap_content" |
|
| 145 |
+ android:layout_height="wrap_content" |
|
| 146 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 147 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 148 |
+ android:textColor="@color/black_day_white_night" |
|
| 149 |
+ android:textSize="@dimen/_24ssp" |
|
| 150 |
+ app:layout_constraintBottom_toTopOf="@+id/btn_record" |
|
| 151 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 152 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 153 |
+ app:layout_constraintTop_toBottomOf="@+id/et_note_description" |
|
| 154 |
+ app:timeText="@{note.audioLength}"
|
|
| 155 |
+ tools:text="00:00" /> |
|
| 156 |
+ |
|
| 157 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 158 |
+ android:id="@+id/btn_record" |
|
| 159 |
+ android:layout_width="wrap_content" |
|
| 160 |
+ android:layout_height="wrap_content" |
|
| 161 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 162 |
+ android:layout_marginBottom="@dimen/_8sdp" |
|
| 163 |
+ android:background="@null" |
|
| 164 |
+ android:contentDescription="@string/record_button" |
|
| 165 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 166 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 167 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 168 |
+ app:layout_constraintTop_toBottomOf="@+id/tv_timer" |
|
| 169 |
+ app:srcCompat="@drawable/ic_mic_not_recording" /> |
|
| 170 |
+ |
|
| 171 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 172 |
+ </ScrollView> |
|
| 173 |
+ |
|
| 174 |
+ <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton |
|
| 175 |
+ android:id="@+id/fab_save_note" |
|
| 176 |
+ android:layout_width="wrap_content" |
|
| 177 |
+ android:layout_height="wrap_content" |
|
| 178 |
+ android:layout_marginEnd="@dimen/_16sdp" |
|
| 179 |
+ android:layout_marginBottom="@dimen/_8sdp" |
|
| 180 |
+ android:backgroundTint="@color/fab_background_tint" |
|
| 181 |
+ android:text="@string/save" |
|
| 182 |
+ android:textAllCaps="false" |
|
| 183 |
+ android:textSize="@dimen/_14ssp" |
|
| 184 |
+ app:icon="@drawable/ic_done_black_24dp" |
|
| 185 |
+ app:iconSize="@dimen/_27sdp" |
|
| 186 |
+ app:layout_constraintBottom_toBottomOf="@+id/scrollView2" |
|
| 187 |
+ app:layout_constraintEnd_toEndOf="parent" /> |
|
| 188 |
+ |
|
| 189 |
+ <com.google.android.material.card.MaterialCardView |
|
| 190 |
+ android:id="@+id/card_add_reminder" |
|
| 191 |
+ android:layout_width="0dp" |
|
| 192 |
+ android:layout_height="wrap_content" |
|
| 193 |
+ android:elevation="@dimen/_4sdp" |
|
| 194 |
+ app:cardBackgroundColor="@null" |
|
| 195 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 196 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 197 |
+ app:layout_constraintStart_toStartOf="parent"> |
|
| 198 |
+ |
|
| 199 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 200 |
+ android:id="@+id/parent_add_reminder" |
|
| 201 |
+ android:layout_width="match_parent" |
|
| 202 |
+ android:layout_height="match_parent" |
|
| 203 |
+ android:background="@{note.color}"
|
|
| 204 |
+ android:backgroundTint="#27FFFFFF" |
|
| 205 |
+ android:backgroundTintMode="screen" |
|
| 206 |
+ android:paddingStart="@dimen/_8sdp" |
|
| 207 |
+ android:paddingTop="@dimen/_4sdp" |
|
| 208 |
+ android:paddingEnd="@dimen/_8sdp" |
|
| 209 |
+ android:paddingBottom="@dimen/_4sdp"> |
|
| 210 |
+ |
|
| 211 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 212 |
+ android:id="@+id/appCompatImageView3" |
|
| 213 |
+ android:layout_width="wrap_content" |
|
| 214 |
+ android:layout_height="wrap_content" |
|
| 215 |
+ android:background="@null" |
|
| 216 |
+ android:padding="@dimen/_4sdp" |
|
| 217 |
+ android:src="@drawable/ic_alarm_on_black_24dp" |
|
| 218 |
+ android:tint="@color/black_day_white_night" |
|
| 219 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 220 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 221 |
+ app:layout_constraintTop_toTopOf="parent" /> |
|
| 222 |
+ |
|
| 223 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 224 |
+ android:id="@+id/tv_reminder_date" |
|
| 225 |
+ android:layout_width="wrap_content" |
|
| 226 |
+ android:layout_height="wrap_content" |
|
| 227 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 228 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 229 |
+ android:padding="@dimen/_4sdp" |
|
| 230 |
+ android:text="@{UtilKt.formatReminderDate(note.reminder)}"
|
|
| 231 |
+ android:textColor="@color/black_day_white_night" |
|
| 232 |
+ android:textSize="@dimen/_14ssp" |
|
| 233 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 234 |
+ app:layout_constraintStart_toEndOf="@+id/appCompatImageView3" |
|
| 235 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 236 |
+ app:strikeThrough="@{viewModel.reminderCompletionState == ReminderCompletionState.COMPLETED}"
|
|
| 237 |
+ app:visible="@{viewModel.reminderAvailableState == ReminderAvailableState.HAS_REMINDER}" />
|
|
| 238 |
+ |
|
| 239 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 240 |
+ android:layout_width="wrap_content" |
|
| 241 |
+ android:layout_height="wrap_content" |
|
| 242 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 243 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 244 |
+ android:text="@string/click_to_add_a_reminder_to_this_note" |
|
| 245 |
+ android:textSize="@dimen/_12ssp" |
|
| 246 |
+ app:layout_constraintBottom_toBottomOf="@+id/appCompatImageView3" |
|
| 247 |
+ app:layout_constraintStart_toEndOf="@+id/appCompatImageView3" |
|
| 248 |
+ app:layout_constraintTop_toTopOf="@+id/appCompatImageView3" |
|
| 249 |
+ app:visible="@{viewModel.reminderAvailableState == ReminderAvailableState.NO_REMINDER}" />
|
|
| 250 |
+ |
|
| 251 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 252 |
+ |
|
| 253 |
+ </com.google.android.material.card.MaterialCardView> |
|
| 254 |
+ |
|
| 255 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 256 |
+</layout> |
|
| 0 | 257 |
\ No newline at end of file |
| 1 | 258 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,285 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<layout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 19 |
+ xmlns:tools="http://schemas.android.com/tools" |
|
| 20 |
+ tools:context=".ui.EditNoteFragment"> |
|
| 21 |
+ |
|
| 22 |
+ <data> |
|
| 23 |
+ |
|
| 24 |
+ <import type="com.certified.audionote.utils.UtilKt" /> |
|
| 25 |
+ |
|
| 26 |
+ <import type="com.certified.audionote.utils.ReminderAvailableState" /> |
|
| 27 |
+ |
|
| 28 |
+ <import type="com.certified.audionote.utils.ReminderCompletionState" /> |
|
| 29 |
+ |
|
| 30 |
+ <variable |
|
| 31 |
+ name="viewModel" |
|
| 32 |
+ type="com.certified.audionote.ui.NotesViewModel" /> |
|
| 33 |
+ |
|
| 34 |
+ <variable |
|
| 35 |
+ name="reminderAvailableState" |
|
| 36 |
+ type="ReminderAvailableState" /> |
|
| 37 |
+ |
|
| 38 |
+ <variable |
|
| 39 |
+ name="reminderCompletionState" |
|
| 40 |
+ type="ReminderCompletionState" /> |
|
| 41 |
+ |
|
| 42 |
+ <variable |
|
| 43 |
+ name="note" |
|
| 44 |
+ type="com.certified.audionote.model.Note" /> |
|
| 45 |
+ </data> |
|
| 46 |
+ |
|
| 47 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 48 |
+ android:id="@+id/parent" |
|
| 49 |
+ android:layout_width="match_parent" |
|
| 50 |
+ android:layout_height="match_parent" |
|
| 51 |
+ android:background="@{note.color}">
|
|
| 52 |
+ |
|
| 53 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 54 |
+ android:id="@+id/btn_back" |
|
| 55 |
+ android:layout_width="wrap_content" |
|
| 56 |
+ android:layout_height="wrap_content" |
|
| 57 |
+ android:layout_gravity="center" |
|
| 58 |
+ android:layout_marginStart="@dimen/_8sdp" |
|
| 59 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 60 |
+ android:background="@null" |
|
| 61 |
+ android:contentDescription="@string/back_button" |
|
| 62 |
+ android:padding="@dimen/_4sdp" |
|
| 63 |
+ android:tint="@color/black_day_white_night" |
|
| 64 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 65 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 66 |
+ app:srcCompat="@drawable/ic_arrow_back_black_24dp" |
|
| 67 |
+ tools:ignore="TouchTargetSizeCheck" /> |
|
| 68 |
+ |
|
| 69 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 70 |
+ android:id="@+id/btn_share" |
|
| 71 |
+ android:layout_width="wrap_content" |
|
| 72 |
+ android:layout_height="wrap_content" |
|
| 73 |
+ android:layout_gravity="center" |
|
| 74 |
+ android:layout_marginEnd="@dimen/_8sdp" |
|
| 75 |
+ android:background="@null" |
|
| 76 |
+ android:contentDescription="@string/share_button" |
|
| 77 |
+ android:padding="@dimen/_4sdp" |
|
| 78 |
+ android:tint="@color/black_day_white_night" |
|
| 79 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 80 |
+ app:layout_constraintTop_toTopOf="@+id/btn_delete" |
|
| 81 |
+ app:srcCompat="@drawable/ic_share_black_24dp" |
|
| 82 |
+ tools:ignore="TouchTargetSizeCheck" /> |
|
| 83 |
+ |
|
| 84 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 85 |
+ android:id="@+id/btn_delete" |
|
| 86 |
+ android:layout_width="wrap_content" |
|
| 87 |
+ android:layout_height="wrap_content" |
|
| 88 |
+ android:layout_marginEnd="@dimen/_8sdp" |
|
| 89 |
+ android:background="@null" |
|
| 90 |
+ android:contentDescription="@string/delete_button" |
|
| 91 |
+ android:padding="@dimen/_4sdp" |
|
| 92 |
+ android:tint="@color/black_day_white_night" |
|
| 93 |
+ app:layout_constraintEnd_toStartOf="@+id/btn_share" |
|
| 94 |
+ app:layout_constraintTop_toTopOf="@+id/btn_back" |
|
| 95 |
+ app:srcCompat="@drawable/ic_delete_black_24dp" |
|
| 96 |
+ tools:ignore="TouchTargetSizeCheck" /> |
|
| 97 |
+ |
|
| 98 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 99 |
+ android:id="@+id/tv_title" |
|
| 100 |
+ android:layout_width="wrap_content" |
|
| 101 |
+ android:layout_height="wrap_content" |
|
| 102 |
+ android:layout_marginStart="@dimen/_32sdp" |
|
| 103 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 104 |
+ android:text="@string/edit_note" |
|
| 105 |
+ android:textColor="@color/black_day_white_night" |
|
| 106 |
+ android:textSize="@dimen/_18ssp" |
|
| 107 |
+ app:layout_constraintBottom_toBottomOf="@+id/btn_back" |
|
| 108 |
+ app:layout_constraintStart_toEndOf="@+id/btn_back" |
|
| 109 |
+ app:layout_constraintTop_toTopOf="@+id/btn_back" /> |
|
| 110 |
+ |
|
| 111 |
+ <ScrollView |
|
| 112 |
+ android:id="@+id/scrollView2" |
|
| 113 |
+ android:layout_width="0dp" |
|
| 114 |
+ android:layout_height="0dp" |
|
| 115 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 116 |
+ android:layout_marginEnd="@dimen/_16sdp" |
|
| 117 |
+ android:paddingTop="@dimen/_16sdp" |
|
| 118 |
+ app:layout_constraintBottom_toTopOf="@+id/card_add_reminder" |
|
| 119 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 120 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 121 |
+ app:layout_constraintTop_toBottomOf="@+id/btn_back"> |
|
| 122 |
+ |
|
| 123 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 124 |
+ android:layout_width="match_parent" |
|
| 125 |
+ android:layout_height="wrap_content"> |
|
| 126 |
+ |
|
| 127 |
+ <com.google.android.material.textfield.TextInputEditText |
|
| 128 |
+ android:id="@+id/et_note_title" |
|
| 129 |
+ android:layout_width="0dp" |
|
| 130 |
+ android:layout_height="wrap_content" |
|
| 131 |
+ android:background="@null" |
|
| 132 |
+ android:fontFamily="@font/open_sans_semi_bold" |
|
| 133 |
+ android:gravity="start|top" |
|
| 134 |
+ android:hint="@string/note_title_required" |
|
| 135 |
+ android:inputType="textMultiLine" |
|
| 136 |
+ android:maxLength="50" |
|
| 137 |
+ android:text="@{note.title}"
|
|
| 138 |
+ android:textSize="@dimen/_16ssp" |
|
| 139 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 140 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 141 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 142 |
+ tools:ignore="TouchTargetSizeCheck,TextContrastCheck" /> |
|
| 143 |
+ |
|
| 144 |
+ <com.google.android.material.textfield.TextInputEditText |
|
| 145 |
+ android:id="@+id/et_note_description" |
|
| 146 |
+ android:layout_width="0dp" |
|
| 147 |
+ android:layout_height="0dp" |
|
| 148 |
+ android:layout_marginTop="@dimen/_10sdp" |
|
| 149 |
+ android:background="@null" |
|
| 150 |
+ android:ems="10" |
|
| 151 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 152 |
+ android:gravity="start|top" |
|
| 153 |
+ android:hint="@string/description" |
|
| 154 |
+ android:inputType="textMultiLine" |
|
| 155 |
+ android:text="@{note.description}"
|
|
| 156 |
+ android:textSize="@dimen/_12ssp" |
|
| 157 |
+ app:layout_constraintBottom_toTopOf="@+id/guideline2" |
|
| 158 |
+ app:layout_constraintEnd_toEndOf="@+id/et_note_title" |
|
| 159 |
+ app:layout_constraintHorizontal_bias="1.0" |
|
| 160 |
+ app:layout_constraintStart_toStartOf="@+id/et_note_title" |
|
| 161 |
+ app:layout_constraintTop_toBottomOf="@+id/et_note_title" |
|
| 162 |
+ tools:ignore="TextContrastCheck" /> |
|
| 163 |
+ |
|
| 164 |
+ <androidx.constraintlayout.widget.Guideline |
|
| 165 |
+ android:id="@+id/guideline2" |
|
| 166 |
+ android:layout_width="wrap_content" |
|
| 167 |
+ android:layout_height="wrap_content" |
|
| 168 |
+ android:orientation="horizontal" |
|
| 169 |
+ app:layout_constraintGuide_percent=".4" /> |
|
| 170 |
+ |
|
| 171 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 172 |
+ android:id="@+id/tv_timer" |
|
| 173 |
+ android:layout_width="wrap_content" |
|
| 174 |
+ android:layout_height="wrap_content" |
|
| 175 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 176 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 177 |
+ android:textColor="@color/black_day_white_night" |
|
| 178 |
+ android:textSize="@dimen/_24ssp" |
|
| 179 |
+ app:layout_constraintBottom_toTopOf="@+id/btn_record" |
|
| 180 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 181 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 182 |
+ app:layout_constraintTop_toBottomOf="@+id/et_note_description" |
|
| 183 |
+ app:timeText="@{note.audioLength}"
|
|
| 184 |
+ tools:text="00:00" /> |
|
| 185 |
+ |
|
| 186 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 187 |
+ android:id="@+id/btn_record" |
|
| 188 |
+ android:layout_width="wrap_content" |
|
| 189 |
+ android:layout_height="wrap_content" |
|
| 190 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 191 |
+ android:layout_marginBottom="@dimen/_8sdp" |
|
| 192 |
+ android:background="@null" |
|
| 193 |
+ android:contentDescription="@string/record_button" |
|
| 194 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 195 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 196 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 197 |
+ app:layout_constraintTop_toBottomOf="@+id/tv_timer" |
|
| 198 |
+ app:srcCompat="@drawable/ic_audio_not_playing" /> |
|
| 199 |
+ |
|
| 200 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 201 |
+ </ScrollView> |
|
| 202 |
+ |
|
| 203 |
+ <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton |
|
| 204 |
+ android:id="@+id/fab_update_note" |
|
| 205 |
+ android:layout_width="wrap_content" |
|
| 206 |
+ android:layout_height="wrap_content" |
|
| 207 |
+ android:layout_marginEnd="@dimen/_16sdp" |
|
| 208 |
+ android:layout_marginBottom="@dimen/_8sdp" |
|
| 209 |
+ android:backgroundTint="@color/fab_background_tint" |
|
| 210 |
+ android:text="@string/save" |
|
| 211 |
+ android:textAllCaps="false" |
|
| 212 |
+ android:textSize="@dimen/_14ssp" |
|
| 213 |
+ app:icon="@drawable/ic_done_black_24dp" |
|
| 214 |
+ app:iconSize="@dimen/_27sdp" |
|
| 215 |
+ app:layout_constraintBottom_toBottomOf="@+id/scrollView2" |
|
| 216 |
+ app:layout_constraintEnd_toEndOf="parent" /> |
|
| 217 |
+ |
|
| 218 |
+ <com.google.android.material.card.MaterialCardView |
|
| 219 |
+ android:id="@+id/card_add_reminder" |
|
| 220 |
+ android:layout_width="0dp" |
|
| 221 |
+ android:layout_height="wrap_content" |
|
| 222 |
+ android:elevation="@dimen/_4sdp" |
|
| 223 |
+ app:cardBackgroundColor="@null" |
|
| 224 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 225 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 226 |
+ app:layout_constraintStart_toStartOf="parent"> |
|
| 227 |
+ |
|
| 228 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 229 |
+ android:id="@+id/parent_add_reminder" |
|
| 230 |
+ android:layout_width="match_parent" |
|
| 231 |
+ android:layout_height="match_parent" |
|
| 232 |
+ android:background="@{note.color}"
|
|
| 233 |
+ android:backgroundTint="#27FFFFFF" |
|
| 234 |
+ android:backgroundTintMode="screen" |
|
| 235 |
+ android:paddingStart="@dimen/_8sdp" |
|
| 236 |
+ android:paddingTop="@dimen/_4sdp" |
|
| 237 |
+ android:paddingEnd="@dimen/_8sdp" |
|
| 238 |
+ android:paddingBottom="@dimen/_4sdp"> |
|
| 239 |
+ |
|
| 240 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 241 |
+ android:id="@+id/appCompatImageView3" |
|
| 242 |
+ android:layout_width="wrap_content" |
|
| 243 |
+ android:layout_height="wrap_content" |
|
| 244 |
+ android:background="@null" |
|
| 245 |
+ android:padding="@dimen/_4sdp" |
|
| 246 |
+ android:src="@drawable/ic_alarm_on_black_24dp" |
|
| 247 |
+ android:tint="@color/black_day_white_night" |
|
| 248 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 249 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 250 |
+ app:layout_constraintTop_toTopOf="parent" /> |
|
| 251 |
+ |
|
| 252 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 253 |
+ android:id="@+id/tv_reminder_date" |
|
| 254 |
+ android:layout_width="wrap_content" |
|
| 255 |
+ android:layout_height="wrap_content" |
|
| 256 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 257 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 258 |
+ android:padding="@dimen/_4sdp" |
|
| 259 |
+ android:text="@{UtilKt.formatReminderDate(note.reminder)}"
|
|
| 260 |
+ android:textColor="@color/black_day_white_night" |
|
| 261 |
+ android:textSize="@dimen/_14ssp" |
|
| 262 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 263 |
+ app:layout_constraintStart_toEndOf="@+id/appCompatImageView3" |
|
| 264 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 265 |
+ app:strikeThrough="@{viewModel.reminderCompletionState == ReminderCompletionState.COMPLETED}"
|
|
| 266 |
+ app:visible="@{viewModel.reminderAvailableState == ReminderAvailableState.HAS_REMINDER}" />
|
|
| 267 |
+ |
|
| 268 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 269 |
+ android:layout_width="wrap_content" |
|
| 270 |
+ android:layout_height="wrap_content" |
|
| 271 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 272 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 273 |
+ android:text="@string/click_to_add_a_reminder_to_this_note" |
|
| 274 |
+ android:textSize="@dimen/_12ssp" |
|
| 275 |
+ app:layout_constraintBottom_toBottomOf="@+id/appCompatImageView3" |
|
| 276 |
+ app:layout_constraintStart_toEndOf="@+id/appCompatImageView3" |
|
| 277 |
+ app:layout_constraintTop_toTopOf="@+id/appCompatImageView3" |
|
| 278 |
+ app:visible="@{viewModel.reminderAvailableState == ReminderAvailableState.NO_REMINDER}" />
|
|
| 279 |
+ |
|
| 280 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 281 |
+ |
|
| 282 |
+ </com.google.android.material.card.MaterialCardView> |
|
| 283 |
+ |
|
| 284 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 285 |
+</layout> |
|
| 0 | 286 |
\ No newline at end of file |
| 1 | 287 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,192 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<layout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 19 |
+ xmlns:tools="http://schemas.android.com/tools"> |
|
| 20 |
+ |
|
| 21 |
+ <data> |
|
| 22 |
+ |
|
| 23 |
+ <import type="androidx.databinding.ObservableField" /> |
|
| 24 |
+ |
|
| 25 |
+ <import type="com.certified.audionote.utils.UIState" /> |
|
| 26 |
+ |
|
| 27 |
+ <variable |
|
| 28 |
+ name="uiState" |
|
| 29 |
+ type="UIState" /> |
|
| 30 |
+ |
|
| 31 |
+ <variable |
|
| 32 |
+ name="viewModel" |
|
| 33 |
+ type="com.certified.audionote.ui.NotesViewModel" /> |
|
| 34 |
+ </data> |
|
| 35 |
+ |
|
| 36 |
+ <androidx.coordinatorlayout.widget.CoordinatorLayout |
|
| 37 |
+ android:layout_width="match_parent" |
|
| 38 |
+ android:background="@color/fragment_background" |
|
| 39 |
+ android:layout_height="match_parent"> |
|
| 40 |
+ |
|
| 41 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 42 |
+ android:layout_width="match_parent" |
|
| 43 |
+ android:layout_height="match_parent" |
|
| 44 |
+ tools:context=".ui.HomeFragment"> |
|
| 45 |
+ |
|
| 46 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 47 |
+ android:id="@+id/btn_settings" |
|
| 48 |
+ android:background="@null" |
|
| 49 |
+ android:padding="@dimen/_4sdp" |
|
| 50 |
+ android:layout_width="wrap_content" |
|
| 51 |
+ android:layout_height="wrap_content" |
|
| 52 |
+ android:layout_gravity="center" |
|
| 53 |
+ android:tint="@color/black_day_white_night" |
|
| 54 |
+ app:srcCompat="@drawable/ic_settings_black_24dp" |
|
| 55 |
+ app:layout_constraintBottom_toBottomOf="@+id/materialTextView3" |
|
| 56 |
+ app:layout_constraintEnd_toEndOf="@+id/fab_add_note" |
|
| 57 |
+ app:layout_constraintTop_toTopOf="@+id/materialTextView2" /> |
|
| 58 |
+ |
|
| 59 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 60 |
+ android:id="@+id/materialTextView2" |
|
| 61 |
+ android:layout_width="wrap_content" |
|
| 62 |
+ android:layout_height="wrap_content" |
|
| 63 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 64 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 65 |
+ android:text="@string/hi_there" |
|
| 66 |
+ android:textSize="@dimen/_18ssp" |
|
| 67 |
+ android:textColor="@color/black_day_white_night" |
|
| 68 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 69 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 70 |
+ app:layout_constraintTop_toTopOf="parent" /> |
|
| 71 |
+ |
|
| 72 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 73 |
+ android:id="@+id/materialTextView3" |
|
| 74 |
+ android:layout_width="wrap_content" |
|
| 75 |
+ android:layout_height="wrap_content" |
|
| 76 |
+ android:alpha=".7" |
|
| 77 |
+ android:text="@string/welcome_back" |
|
| 78 |
+ android:fontFamily="@font/open_sans_medium" |
|
| 79 |
+ android:textSize="@dimen/_12ssp" |
|
| 80 |
+ app:layout_constraintStart_toStartOf="@+id/materialTextView2" |
|
| 81 |
+ app:layout_constraintTop_toBottomOf="@+id/materialTextView2" /> |
|
| 82 |
+ |
|
| 83 |
+ <androidx.recyclerview.widget.RecyclerView |
|
| 84 |
+ android:id="@+id/recycler_view_notes" |
|
| 85 |
+ android:layout_width="0dp" |
|
| 86 |
+ android:layout_height="0dp" |
|
| 87 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 88 |
+ android:layout_marginStart="@dimen/_8sdp" |
|
| 89 |
+ android:layout_marginEnd="@dimen/_8sdp" |
|
| 90 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 91 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 92 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 93 |
+ app:layout_constraintTop_toBottomOf="@+id/materialTextView3" |
|
| 94 |
+ app:listItems="@{viewModel.notes}"
|
|
| 95 |
+ app:visible="@{viewModel.uiState == UIState.HAS_DATA}"
|
|
| 96 |
+ tools:listitem="@layout/item_note" /> |
|
| 97 |
+ |
|
| 98 |
+<!-- <com.google.android.material.textview.MaterialTextView--> |
|
| 99 |
+<!-- android:id="@+id/materialTextView"--> |
|
| 100 |
+<!-- android:layout_width="0dp"--> |
|
| 101 |
+<!-- android:textColor="@color/titleText"--> |
|
| 102 |
+<!-- android:layout_marginEnd="@dimen/_16sdp"--> |
|
| 103 |
+<!-- android:layout_marginStart="@dimen/_16sdp"--> |
|
| 104 |
+<!-- android:layout_height="wrap_content"--> |
|
| 105 |
+<!-- android:text="“The more that you read, the more things you will know, the more that you learn, the more places you’ll go.”"--> |
|
| 106 |
+<!-- android:textAlignment="center"--> |
|
| 107 |
+<!-- android:alpha=".7"--> |
|
| 108 |
+<!-- android:textSize="@dimen/_14ssp"--> |
|
| 109 |
+<!-- android:fontFamily="@font/open_sans_medium_italic"--> |
|
| 110 |
+<!-- app:layout_constraintBottom_toTopOf="@+id/materialTextView4"--> |
|
| 111 |
+<!-- app:layout_constraintEnd_toEndOf="parent"--> |
|
| 112 |
+<!-- app:layout_constraintHorizontal_bias="0.5"--> |
|
| 113 |
+<!-- app:layout_constraintStart_toStartOf="parent"--> |
|
| 114 |
+<!-- app:layout_constraintTop_toTopOf="parent"--> |
|
| 115 |
+<!-- app:layout_constraintVertical_chainStyle="packed" />--> |
|
| 116 |
+ |
|
| 117 |
+<!-- <com.google.android.material.textview.MaterialTextView--> |
|
| 118 |
+<!-- android:id="@+id/materialTextView4"--> |
|
| 119 |
+<!-- android:layout_width="wrap_content"--> |
|
| 120 |
+<!-- android:layout_height="wrap_content"--> |
|
| 121 |
+<!-- android:text="– Dr. Seuss"--> |
|
| 122 |
+<!-- android:scrollbarSize="@dimen/_18ssp"--> |
|
| 123 |
+<!-- android:textColor="@color/titleText"--> |
|
| 124 |
+<!-- android:fontFamily="@font/open_sans_bold_italic"--> |
|
| 125 |
+<!-- android:textSize="@dimen/_18ssp"--> |
|
| 126 |
+<!-- app:layout_constraintBottom_toBottomOf="parent"--> |
|
| 127 |
+<!-- app:layout_constraintEnd_toEndOf="@+id/materialTextView"--> |
|
| 128 |
+<!-- app:layout_constraintHorizontal_bias="0.5"--> |
|
| 129 |
+<!-- app:layout_constraintStart_toStartOf="@+id/materialTextView"--> |
|
| 130 |
+<!-- app:layout_constraintTop_toBottomOf="@+id/materialTextView" />--> |
|
| 131 |
+ |
|
| 132 |
+ <androidx.appcompat.widget.AppCompatImageView |
|
| 133 |
+ android:id="@+id/iv_empty_notes" |
|
| 134 |
+ android:layout_width="0dp" |
|
| 135 |
+ android:layout_height="0dp" |
|
| 136 |
+ android:layout_margin="@dimen/_16sdp" |
|
| 137 |
+ android:src="@drawable/ic_undraw_empty" |
|
| 138 |
+ app:layout_constraintBottom_toTopOf="@+id/fab_add_note" |
|
| 139 |
+ app:layout_constraintEnd_toEndOf="@+id/fab_add_note" |
|
| 140 |
+ app:layout_constraintHorizontal_bias="1.0" |
|
| 141 |
+ app:layout_constraintStart_toStartOf="@+id/materialTextView3" |
|
| 142 |
+ app:layout_constraintTop_toBottomOf="@+id/materialTextView3" |
|
| 143 |
+ app:layout_constraintVertical_bias="1.0" /> |
|
| 144 |
+ |
|
| 145 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 146 |
+ android:id="@+id/tv_empty_notes" |
|
| 147 |
+ android:layout_width="wrap_content" |
|
| 148 |
+ android:layout_height="wrap_content" |
|
| 149 |
+ android:layout_marginBottom="@dimen/_8sdp" |
|
| 150 |
+ android:alpha=".7" |
|
| 151 |
+ app:fontFamily="@font/open_sans_semi_bold" |
|
| 152 |
+ android:textColor="@color/titleText" |
|
| 153 |
+ android:paddingStart="@dimen/_16sdp" |
|
| 154 |
+ android:paddingEnd="@dimen/_16sdp" |
|
| 155 |
+ android:text="@string/your_record_list_is_empty_click_the_button_below_to_get_started" |
|
| 156 |
+ android:textAlignment="center" |
|
| 157 |
+ android:textSize="@dimen/_12ssp" |
|
| 158 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 159 |
+ app:layout_constraintBottom_toBottomOf="@+id/iv_empty_notes" |
|
| 160 |
+ app:layout_constraintEnd_toEndOf="@+id/iv_empty_notes" |
|
| 161 |
+ app:layout_constraintStart_toStartOf="@+id/iv_empty_notes" /> |
|
| 162 |
+ |
|
| 163 |
+ <androidx.constraintlayout.widget.Group |
|
| 164 |
+ android:id="@+id/group_empty_notes" |
|
| 165 |
+ android:layout_width="wrap_content" |
|
| 166 |
+ android:layout_height="wrap_content" |
|
| 167 |
+ android:visibility="visible" |
|
| 168 |
+ app:constraint_referenced_ids="iv_empty_notes, tv_empty_notes" |
|
| 169 |
+ app:visible="@{viewModel.uiState == UIState.EMPTY}" />
|
|
| 170 |
+ |
|
| 171 |
+ <com.google.android.material.floatingactionbutton.FloatingActionButton |
|
| 172 |
+ android:id="@+id/fab_add_note" |
|
| 173 |
+ android:layout_width="wrap_content" |
|
| 174 |
+ android:layout_height="wrap_content" |
|
| 175 |
+ android:layout_marginEnd="@dimen/_16sdp" |
|
| 176 |
+ android:layout_marginBottom="@dimen/_16sdp" |
|
| 177 |
+ android:backgroundTint="@color/fab_background_tint" |
|
| 178 |
+ android:contentDescription="@string/add_note_button" |
|
| 179 |
+ app:iconSize="@dimen/_27sdp" |
|
| 180 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 181 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 182 |
+ app:srcCompat="@drawable/ic_mic_black_24dp" /> |
|
| 183 |
+ |
|
| 184 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 185 |
+ |
|
| 186 |
+ <include |
|
| 187 |
+ android:visibility="gone" |
|
| 188 |
+ android:id="@+id/bottom_sheet_dialog_layout" |
|
| 189 |
+ layout="@layout/bottom_sheet_dialog" /> |
|
| 190 |
+ |
|
| 191 |
+ </androidx.coordinatorlayout.widget.CoordinatorLayout> |
|
| 192 |
+</layout> |
|
| 0 | 193 |
\ No newline at end of file |
| 1 | 194 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,86 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
+<!-- |
|
| 3 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 4 |
+ ~ |
|
| 5 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ ~ you may not use this file except in compliance with the License. |
|
| 7 |
+ ~ You may obtain a copy of the License at |
|
| 8 |
+ ~ |
|
| 9 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ ~ |
|
| 11 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ ~ See the License for the specific language governing permissions and |
|
| 15 |
+ ~ limitations under the License. |
|
| 16 |
+ --> |
|
| 17 |
+ |
|
| 18 |
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 19 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 20 |
+ xmlns:tools="http://schemas.android.com/tools" |
|
| 21 |
+ android:layout_width="match_parent" |
|
| 22 |
+ android:layout_height="match_parent" |
|
| 23 |
+ android:background="@color/fragment_background" |
|
| 24 |
+ tools:context=".ui.OnboardingFragment"> |
|
| 25 |
+ |
|
| 26 |
+ <androidx.viewpager2.widget.ViewPager2 |
|
| 27 |
+ android:id="@+id/view_pager" |
|
| 28 |
+ android:layout_width="0dp" |
|
| 29 |
+ android:layout_height="0dp" |
|
| 30 |
+ android:layout_marginTop="16dp" |
|
| 31 |
+ android:layout_marginBottom="16dp" |
|
| 32 |
+ app:layout_constraintBottom_toTopOf="@+id/btn_get_started" |
|
| 33 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 34 |
+ app:layout_constraintHorizontal_bias="0.0" |
|
| 35 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 36 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 37 |
+ app:layout_constraintVertical_bias="0.0" /> |
|
| 38 |
+ |
|
| 39 |
+ <com.google.android.material.button.MaterialButton |
|
| 40 |
+ android:id="@+id/btn_get_started" |
|
| 41 |
+ android:layout_width="0dp" |
|
| 42 |
+ android:layout_height="wrap_content" |
|
| 43 |
+ android:layout_marginBottom="@dimen/_16sdp" |
|
| 44 |
+ android:backgroundTint="@color/primary_dark" |
|
| 45 |
+ android:fontFamily="@font/open_sans_semi_bold" |
|
| 46 |
+ android:text="@string/get_started" |
|
| 47 |
+ android:textSize="@dimen/_14ssp" |
|
| 48 |
+ android:textAllCaps="false" |
|
| 49 |
+ android:textColor="@color/black_day_white_night" |
|
| 50 |
+ app:layout_constraintBottom_toTopOf="@+id/indicator" |
|
| 51 |
+ app:layout_constraintEnd_toStartOf="@+id/guideline5" |
|
| 52 |
+ app:layout_constraintStart_toStartOf="@+id/guideline4" /> |
|
| 53 |
+ |
|
| 54 |
+ <com.rd.PageIndicatorView |
|
| 55 |
+ android:id="@+id/indicator" |
|
| 56 |
+ android:layout_width="wrap_content" |
|
| 57 |
+ android:layout_height="wrap_content" |
|
| 58 |
+ android:layout_marginBottom="@dimen/_64sdp" |
|
| 59 |
+ android:background="@android:color/transparent" |
|
| 60 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 61 |
+ app:layout_constraintEnd_toEndOf="@+id/btn_get_started" |
|
| 62 |
+ app:layout_constraintStart_toStartOf="@+id/btn_get_started" |
|
| 63 |
+ app:piv_animationType="worm" |
|
| 64 |
+ app:piv_count="3" |
|
| 65 |
+ app:piv_dynamicCount="true" |
|
| 66 |
+ app:piv_interactiveAnimation="true" |
|
| 67 |
+ app:piv_padding="6dp" |
|
| 68 |
+ app:piv_selectedColor="@color/primary_dark" |
|
| 69 |
+ app:piv_unselectedColor="@color/grey" |
|
| 70 |
+ app:piv_viewPager="@id/view_pager" /> |
|
| 71 |
+ |
|
| 72 |
+ <androidx.constraintlayout.widget.Guideline |
|
| 73 |
+ android:id="@+id/guideline4" |
|
| 74 |
+ android:layout_width="wrap_content" |
|
| 75 |
+ android:layout_height="wrap_content" |
|
| 76 |
+ android:orientation="vertical" |
|
| 77 |
+ app:layout_constraintGuide_percent=".3"/> |
|
| 78 |
+ |
|
| 79 |
+ <androidx.constraintlayout.widget.Guideline |
|
| 80 |
+ android:id="@+id/guideline5" |
|
| 81 |
+ android:layout_width="wrap_content" |
|
| 82 |
+ android:layout_height="wrap_content" |
|
| 83 |
+ android:orientation="vertical" |
|
| 84 |
+ app:layout_constraintGuide_percent=".7"/> |
|
| 85 |
+ |
|
| 86 |
+</androidx.constraintlayout.widget.ConstraintLayout> |
|
| 0 | 87 |
\ No newline at end of file |
| 1 | 88 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,126 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<layout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto"> |
|
| 19 |
+ |
|
| 20 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 21 |
+ android:layout_width="match_parent" |
|
| 22 |
+ android:layout_height="match_parent" |
|
| 23 |
+ android:background="@color/fragment_background"> |
|
| 24 |
+ |
|
| 25 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 26 |
+ android:id="@+id/btn_back" |
|
| 27 |
+ android:layout_width="wrap_content" |
|
| 28 |
+ android:layout_height="wrap_content" |
|
| 29 |
+ android:layout_gravity="center" |
|
| 30 |
+ android:background="@null" |
|
| 31 |
+ android:padding="@dimen/_4sdp" |
|
| 32 |
+ android:tint="@color/black_day_white_night" |
|
| 33 |
+ android:layout_marginStart="@dimen/_8sdp" |
|
| 34 |
+ app:layout_constraintBottom_toBottomOf="@+id/materialTextView" |
|
| 35 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 36 |
+ app:layout_constraintTop_toTopOf="@+id/materialTextView" |
|
| 37 |
+ app:srcCompat="@drawable/ic_arrow_back_black_24dp" /> |
|
| 38 |
+ |
|
| 39 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 40 |
+ android:id="@+id/materialTextView" |
|
| 41 |
+ android:layout_width="wrap_content" |
|
| 42 |
+ android:layout_height="wrap_content" |
|
| 43 |
+ android:layout_marginStart="@dimen/_32sdp" |
|
| 44 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 45 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 46 |
+ android:text="@string/settings" |
|
| 47 |
+ android:textColor="@color/black_day_white_night" |
|
| 48 |
+ android:textSize="@dimen/_22ssp" |
|
| 49 |
+ app:layout_constraintStart_toEndOf="@+id/btn_back" |
|
| 50 |
+ app:layout_constraintTop_toTopOf="parent" /> |
|
| 51 |
+ |
|
| 52 |
+ <ScrollView |
|
| 53 |
+ android:layout_width="0dp" |
|
| 54 |
+ android:layout_height="0dp" |
|
| 55 |
+ android:layout_marginStart="@dimen/_16sdp" |
|
| 56 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 57 |
+ android:layout_marginEnd="@dimen/_16sdp" |
|
| 58 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 59 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 60 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 61 |
+ app:layout_constraintTop_toBottomOf="@+id/btn_back"> |
|
| 62 |
+ |
|
| 63 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 64 |
+ android:layout_width="match_parent" |
|
| 65 |
+ android:layout_height="wrap_content"> |
|
| 66 |
+ |
|
| 67 |
+ <androidx.fragment.app.FragmentContainerView |
|
| 68 |
+ android:id="@+id/preference_fragment" |
|
| 69 |
+ android:name="com.certified.audionote.ui.PreferenceFragment" |
|
| 70 |
+ android:layout_width="0dp" |
|
| 71 |
+ android:layout_height="wrap_content" |
|
| 72 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 73 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 74 |
+ app:layout_constraintTop_toTopOf="parent" /> |
|
| 75 |
+ |
|
| 76 |
+ <androidx.appcompat.widget.AppCompatImageView |
|
| 77 |
+ android:id="@+id/appCompatImageView4" |
|
| 78 |
+ android:layout_width="wrap_content" |
|
| 79 |
+ android:layout_height="wrap_content" |
|
| 80 |
+ android:layout_marginStart="@dimen/_12sdp" |
|
| 81 |
+ android:src="@drawable/ic_info_black_24dp" |
|
| 82 |
+ app:layout_constraintBottom_toBottomOf="@+id/materialTextView9" |
|
| 83 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 84 |
+ app:layout_constraintTop_toTopOf="@+id/materialTextView8" /> |
|
| 85 |
+ |
|
| 86 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 87 |
+ android:id="@+id/materialTextView8" |
|
| 88 |
+ android:layout_width="wrap_content" |
|
| 89 |
+ android:layout_height="wrap_content" |
|
| 90 |
+ android:layout_marginStart="@dimen/_20sdp" |
|
| 91 |
+ android:layout_marginTop="@dimen/_8sdp" |
|
| 92 |
+ android:text="@string/about" |
|
| 93 |
+ android:fontFamily="@font/open_sans_semi_bold" |
|
| 94 |
+ android:textSize="@dimen/_14ssp" |
|
| 95 |
+ android:textColor="@color/black_day_white_night" |
|
| 96 |
+ app:layout_constraintStart_toEndOf="@+id/appCompatImageView4" |
|
| 97 |
+ app:layout_constraintTop_toBottomOf="@+id/preference_fragment" /> |
|
| 98 |
+ |
|
| 99 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 100 |
+ android:id="@+id/materialTextView9" |
|
| 101 |
+ android:layout_width="wrap_content" |
|
| 102 |
+ android:layout_height="wrap_content" |
|
| 103 |
+ android:layout_marginBottom="@dimen/_4sdp" |
|
| 104 |
+ android:textSize="@dimen/_11ssp" |
|
| 105 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 106 |
+ android:text= "@string/app_version_licence_and_more" |
|
| 107 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 108 |
+ app:layout_constraintStart_toStartOf="@+id/materialTextView8" |
|
| 109 |
+ app:layout_constraintTop_toBottomOf="@+id/materialTextView8" /> |
|
| 110 |
+ |
|
| 111 |
+ <androidx.constraintlayout.widget.Group |
|
| 112 |
+ android:id="@+id/group_about" |
|
| 113 |
+ android:layout_width="0dp" |
|
| 114 |
+ android:layout_height="0dp" |
|
| 115 |
+ app:constraint_referenced_ids="materialTextView9,materialTextView8" |
|
| 116 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 117 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 118 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 119 |
+ app:layout_constraintTop_toTopOf="@+id/materialTextView8" /> |
|
| 120 |
+ |
|
| 121 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 122 |
+ |
|
| 123 |
+ </ScrollView> |
|
| 124 |
+ |
|
| 125 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 126 |
+</layout> |
|
| 0 | 127 |
\ No newline at end of file |
| 1 | 128 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,185 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<layout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 19 |
+ xmlns:tools="http://schemas.android.com/tools"> |
|
| 20 |
+ |
|
| 21 |
+ <data> |
|
| 22 |
+ |
|
| 23 |
+ <import type="com.certified.audionote.utils.Extensions" /> |
|
| 24 |
+ |
|
| 25 |
+ <import type="com.certified.audionote.utils.UtilKt" /> |
|
| 26 |
+ |
|
| 27 |
+ <variable |
|
| 28 |
+ name="note" |
|
| 29 |
+ type="com.certified.audionote.model.Note" /> |
|
| 30 |
+ </data> |
|
| 31 |
+ |
|
| 32 |
+ <com.google.android.material.card.MaterialCardView |
|
| 33 |
+ android:layout_width="match_parent" |
|
| 34 |
+ android:layout_height="wrap_content" |
|
| 35 |
+ app:cardBackgroundColor="@{note.color}"
|
|
| 36 |
+ app:cardCornerRadius="@dimen/_8sdp" |
|
| 37 |
+ app:cardElevation="@dimen/_4sdp" |
|
| 38 |
+ app:cardUseCompatPadding="true"> |
|
| 39 |
+ |
|
| 40 |
+ <androidx.constraintlayout.widget.ConstraintLayout |
|
| 41 |
+ android:layout_width="match_parent" |
|
| 42 |
+ android:layout_height="wrap_content" |
|
| 43 |
+ android:background="@{note.color}"
|
|
| 44 |
+ android:paddingBottom="@dimen/_8sdp"> |
|
| 45 |
+ |
|
| 46 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 47 |
+ android:id="@+id/tv_note_title" |
|
| 48 |
+ android:layout_width="0dp" |
|
| 49 |
+ android:layout_height="wrap_content" |
|
| 50 |
+ android:layout_marginStart="@dimen/_8sdp" |
|
| 51 |
+ android:layout_marginTop="@dimen/_8sdp" |
|
| 52 |
+ android:layout_marginEnd="@dimen/_4sdp" |
|
| 53 |
+ android:ellipsize="end" |
|
| 54 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 55 |
+ android:maxLines="1" |
|
| 56 |
+ android:text="@{note.title}"
|
|
| 57 |
+ android:textColor="@color/white" |
|
| 58 |
+ android:textSize="@dimen/_12ssp" |
|
| 59 |
+ app:layout_constraintEnd_toStartOf="@+id/tv_note_last_modification_date" |
|
| 60 |
+ app:layout_constraintHorizontal_bias="0.5" |
|
| 61 |
+ app:layout_constraintHorizontal_chainStyle="spread_inside" |
|
| 62 |
+ app:layout_constraintHorizontal_weight="4" |
|
| 63 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 64 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 65 |
+ tools:text="CPE 407 - Lecture 1" /> |
|
| 66 |
+ |
|
| 67 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 68 |
+ android:id="@+id/tv_note_last_modification_date" |
|
| 69 |
+ android:layout_width="0dp" |
|
| 70 |
+ android:layout_height="wrap_content" |
|
| 71 |
+ android:layout_marginEnd="@dimen/_8sdp" |
|
| 72 |
+ android:ellipsize="end" |
|
| 73 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 74 |
+ android:maxLines="1" |
|
| 75 |
+ android:text="@{UtilKt.formatDate(note.lastModificationDate, context)}"
|
|
| 76 |
+ android:textAlignment="viewEnd" |
|
| 77 |
+ android:textColor="@color/white" |
|
| 78 |
+ android:textSize="@dimen/_10ssp" |
|
| 79 |
+ app:layout_constraintBottom_toBottomOf="@+id/tv_note_title" |
|
| 80 |
+ app:layout_constraintEnd_toEndOf="parent" |
|
| 81 |
+ app:layout_constraintHorizontal_bias="0.5" |
|
| 82 |
+ app:layout_constraintHorizontal_weight="2" |
|
| 83 |
+ app:layout_constraintStart_toEndOf="@+id/tv_note_title" |
|
| 84 |
+ app:layout_constraintTop_toTopOf="@+id/tv_note_title" |
|
| 85 |
+ tools:text="17/11/21" /> |
|
| 86 |
+ |
|
| 87 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 88 |
+ android:id="@+id/appCompatImageView" |
|
| 89 |
+ android:layout_width="wrap_content" |
|
| 90 |
+ android:layout_height="wrap_content" |
|
| 91 |
+ android:layout_marginTop="@dimen/_8sdp" |
|
| 92 |
+ android:background="@null" |
|
| 93 |
+ android:padding="@dimen/_4sdp" |
|
| 94 |
+ android:tint="@color/white" |
|
| 95 |
+ app:layout_constraintEnd_toStartOf="@+id/tv_record_length" |
|
| 96 |
+ app:layout_constraintHorizontal_bias="0.5" |
|
| 97 |
+ app:layout_constraintHorizontal_chainStyle="spread_inside" |
|
| 98 |
+ app:layout_constraintStart_toStartOf="parent" |
|
| 99 |
+ app:layout_constraintTop_toBottomOf="@+id/tv_note_title" |
|
| 100 |
+ app:srcCompat="@drawable/ic_mic_black_24dp" /> |
|
| 101 |
+ |
|
| 102 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 103 |
+ android:id="@+id/tv_record_length" |
|
| 104 |
+ android:layout_width="wrap_content" |
|
| 105 |
+ android:layout_height="wrap_content" |
|
| 106 |
+ android:fontFamily="@font/open_sans_bold" |
|
| 107 |
+ android:textColor="@color/white" |
|
| 108 |
+ android:textSize="@dimen/_12ssp" |
|
| 109 |
+ app:layout_constraintBottom_toBottomOf="@+id/appCompatImageView" |
|
| 110 |
+ app:layout_constraintEnd_toStartOf="@+id/tv_note_size" |
|
| 111 |
+ app:layout_constraintHorizontal_bias="0.5" |
|
| 112 |
+ app:layout_constraintStart_toEndOf="@+id/appCompatImageView" |
|
| 113 |
+ app:layout_constraintTop_toTopOf="@+id/appCompatImageView" |
|
| 114 |
+ app:timeText="@{note.audioLength}"
|
|
| 115 |
+ tools:text="36:25" /> |
|
| 116 |
+ |
|
| 117 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 118 |
+ android:id="@+id/tv_note_size" |
|
| 119 |
+ android:layout_width="wrap_content" |
|
| 120 |
+ android:layout_height="wrap_content" |
|
| 121 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 122 |
+ android:textColor="@color/white" |
|
| 123 |
+ android:textSize="@dimen/_12ssp" |
|
| 124 |
+ app:layout_constraintEnd_toEndOf="@+id/tv_note_last_modification_date" |
|
| 125 |
+ app:layout_constraintHorizontal_bias="0.5" |
|
| 126 |
+ app:layout_constraintStart_toEndOf="@+id/tv_record_length" |
|
| 127 |
+ app:layout_constraintTop_toTopOf="@+id/tv_record_length" |
|
| 128 |
+ app:sizeText="@{note.size}"
|
|
| 129 |
+ tools:text="46MB" /> |
|
| 130 |
+ |
|
| 131 |
+ <androidx.appcompat.widget.AppCompatImageButton |
|
| 132 |
+ android:id="@+id/appCompatImageView2" |
|
| 133 |
+ android:layout_width="wrap_content" |
|
| 134 |
+ android:layout_height="wrap_content" |
|
| 135 |
+ android:layout_marginTop="@dimen/_8sdp" |
|
| 136 |
+ android:alpha=".6" |
|
| 137 |
+ android:background="@null" |
|
| 138 |
+ android:padding="@dimen/_4sdp" |
|
| 139 |
+ android:tint="@color/white" |
|
| 140 |
+ app:layout_constraintStart_toStartOf="@+id/appCompatImageView" |
|
| 141 |
+ app:layout_constraintTop_toBottomOf="@+id/appCompatImageView" |
|
| 142 |
+ app:srcCompat="@drawable/ic_alarm_on_black_24dp" /> |
|
| 143 |
+ |
|
| 144 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 145 |
+ android:id="@+id/tv_reminder_time" |
|
| 146 |
+ android:layout_width="0dp" |
|
| 147 |
+ android:layout_height="wrap_content" |
|
| 148 |
+ android:layout_marginStart="@dimen/_4sdp" |
|
| 149 |
+ android:alpha=".6" |
|
| 150 |
+ android:ellipsize="end" |
|
| 151 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 152 |
+ android:maxLines="1" |
|
| 153 |
+ android:text="@{UtilKt.formatReminderDate(note.reminder)}"
|
|
| 154 |
+ android:textAlignment="textEnd" |
|
| 155 |
+ android:textColor="@color/white" |
|
| 156 |
+ android:textSize="@dimen/_12ssp" |
|
| 157 |
+ app:layout_constraintBottom_toBottomOf="@+id/appCompatImageView2" |
|
| 158 |
+ app:layout_constraintEnd_toEndOf="@+id/tv_note_size" |
|
| 159 |
+ app:layout_constraintStart_toEndOf="@+id/appCompatImageView2" |
|
| 160 |
+ app:layout_constraintTop_toTopOf="@+id/appCompatImageView2" |
|
| 161 |
+ app:strikeThrough="@{UtilKt.currentDate().timeInMillis > note.reminder}"
|
|
| 162 |
+ app:visible="@{note.reminder != null}" />
|
|
| 163 |
+ <!-- tools:text="17 Nov, 2021 8:00 AM"--> |
|
| 164 |
+ |
|
| 165 |
+ <com.google.android.material.textview.MaterialTextView |
|
| 166 |
+ android:layout_width="0dp" |
|
| 167 |
+ android:layout_height="wrap_content" |
|
| 168 |
+ android:layout_marginStart="@dimen/_4sdp" |
|
| 169 |
+ android:ellipsize="end" |
|
| 170 |
+ android:fontFamily="@font/open_sans_regular" |
|
| 171 |
+ android:maxLines="1" |
|
| 172 |
+ android:text="@string/no_reminder_set" |
|
| 173 |
+ android:textAlignment="viewEnd" |
|
| 174 |
+ android:textColor="@color/white" |
|
| 175 |
+ android:textSize="@dimen/_12ssp" |
|
| 176 |
+ app:layout_constraintBottom_toBottomOf="@+id/appCompatImageView2" |
|
| 177 |
+ app:layout_constraintEnd_toEndOf="@+id/tv_note_size" |
|
| 178 |
+ app:layout_constraintStart_toEndOf="@+id/appCompatImageView2" |
|
| 179 |
+ app:layout_constraintTop_toTopOf="@+id/appCompatImageView2" |
|
| 180 |
+ app:visible="@{note.reminder == null}" />
|
|
| 181 |
+ |
|
| 182 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 183 |
+ |
|
| 184 |
+ </com.google.android.material.card.MaterialCardView> |
|
| 185 |
+</layout> |
|
| 0 | 186 |
\ No newline at end of file |
| 1 | 187 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,94 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<layout xmlns:tools="http://schemas.android.com/tools" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto"> |
|
| 19 |
+ |
|
| 20 |
+ <data> |
|
| 21 |
+ |
|
| 22 |
+ <variable |
|
| 23 |
+ name="sliderItem" |
|
| 24 |
+ type="com.certified.audionote.model.SliderItem" /> |
|
| 25 |
+ </data> |
|
| 26 |
+ |
|
| 27 |
+ <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 28 |
+ android:layout_width="match_parent" |
|
| 29 |
+ android:layout_height="match_parent"> |
|
| 30 |
+ |
|
| 31 |
+ <androidx.appcompat.widget.AppCompatImageView |
|
| 32 |
+ android:id="@+id/animation_view" |
|
| 33 |
+ android:layout_width="0dp" |
|
| 34 |
+ app:image="@{sliderItem.image}"
|
|
| 35 |
+ android:layout_height="0dp" |
|
| 36 |
+ app:layout_constraintBottom_toTopOf="@+id/tv_title" |
|
| 37 |
+ app:layout_constraintDimensionRatio="1:1" |
|
| 38 |
+ app:layout_constraintEnd_toStartOf="@+id/guideline2" |
|
| 39 |
+ app:layout_constraintHorizontal_bias="0.5" |
|
| 40 |
+ app:layout_constraintStart_toStartOf="@+id/guideline" |
|
| 41 |
+ app:layout_constraintTop_toTopOf="parent" |
|
| 42 |
+ app:layout_constraintVertical_chainStyle="packed"/> |
|
| 43 |
+ |
|
| 44 |
+ <TextView |
|
| 45 |
+ android:id="@+id/tv_title" |
|
| 46 |
+ android:fontFamily="@font/open_sans_bold_italic" |
|
| 47 |
+ android:textColor="@color/titleText" |
|
| 48 |
+ android:layout_width="0dp" |
|
| 49 |
+ android:layout_height="wrap_content" |
|
| 50 |
+ android:layout_marginTop="@dimen/_16sdp" |
|
| 51 |
+ android:textAlignment="center" |
|
| 52 |
+ android:text="@{sliderItem.title}"
|
|
| 53 |
+ android:textSize="@dimen/_18ssp" |
|
| 54 |
+ app:layout_constraintBottom_toTopOf="@+id/tv_description" |
|
| 55 |
+ app:layout_constraintEnd_toStartOf="@+id/guideline2" |
|
| 56 |
+ app:layout_constraintHorizontal_bias="0.5" |
|
| 57 |
+ app:layout_constraintStart_toStartOf="@+id/guideline" |
|
| 58 |
+ app:layout_constraintTop_toBottomOf="@+id/animation_view" |
|
| 59 |
+ tools:text="TextView" /> |
|
| 60 |
+ |
|
| 61 |
+ <TextView |
|
| 62 |
+ android:id="@+id/tv_description" |
|
| 63 |
+ android:textColor="@color/titleText" |
|
| 64 |
+ android:fontFamily="@font/open_sans_medium_italic" |
|
| 65 |
+ android:layout_width="0dp" |
|
| 66 |
+ android:layout_height="wrap_content" |
|
| 67 |
+ android:alpha=".7" |
|
| 68 |
+ android:layout_marginTop="@dimen/_8sdp" |
|
| 69 |
+ android:gravity="center" |
|
| 70 |
+ android:text="@{sliderItem.description}"
|
|
| 71 |
+ android:textSize="@dimen/_12ssp" |
|
| 72 |
+ app:layout_constraintBottom_toBottomOf="parent" |
|
| 73 |
+ app:layout_constraintEnd_toStartOf="@+id/guideline2" |
|
| 74 |
+ app:layout_constraintHorizontal_bias="0.5" |
|
| 75 |
+ app:layout_constraintStart_toStartOf="@+id/guideline" |
|
| 76 |
+ app:layout_constraintTop_toBottomOf="@+id/tv_title" |
|
| 77 |
+ tools:text="TextView" /> |
|
| 78 |
+ |
|
| 79 |
+ <androidx.constraintlayout.widget.Guideline |
|
| 80 |
+ android:id="@+id/guideline" |
|
| 81 |
+ android:layout_width="wrap_content" |
|
| 82 |
+ android:layout_height="wrap_content" |
|
| 83 |
+ android:orientation="vertical" |
|
| 84 |
+ app:layout_constraintGuide_percent="0.1" /> |
|
| 85 |
+ |
|
| 86 |
+ <androidx.constraintlayout.widget.Guideline |
|
| 87 |
+ android:id="@+id/guideline2" |
|
| 88 |
+ android:layout_width="wrap_content" |
|
| 89 |
+ android:layout_height="wrap_content" |
|
| 90 |
+ android:orientation="vertical" |
|
| 91 |
+ app:layout_constraintGuide_percent="0.9" /> |
|
| 92 |
+ |
|
| 93 |
+ </androidx.constraintlayout.widget.ConstraintLayout> |
|
| 94 |
+</layout> |
|
| 0 | 95 |
\ No newline at end of file |
| 1 | 96 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,22 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
+<!-- |
|
| 3 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 4 |
+ ~ |
|
| 5 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ ~ you may not use this file except in compliance with the License. |
|
| 7 |
+ ~ You may obtain a copy of the License at |
|
| 8 |
+ ~ |
|
| 9 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ ~ |
|
| 11 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ ~ See the License for the specific language governing permissions and |
|
| 15 |
+ ~ limitations under the License. |
|
| 16 |
+ --> |
|
| 17 |
+ |
|
| 18 |
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 19 |
+ <background android:drawable="@color/ic_logo_background"/> |
|
| 20 |
+ <foreground android:drawable="@drawable/ic_logo_foreground"/> |
|
| 21 |
+ <monochrome android:drawable="@drawable/ic_logo" /> |
|
| 22 |
+</adaptive-icon> |
|
| 0 | 23 |
\ No newline at end of file |
| 1 | 24 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,22 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
+<!-- |
|
| 3 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 4 |
+ ~ |
|
| 5 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ ~ you may not use this file except in compliance with the License. |
|
| 7 |
+ ~ You may obtain a copy of the License at |
|
| 8 |
+ ~ |
|
| 9 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ ~ |
|
| 11 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ ~ See the License for the specific language governing permissions and |
|
| 15 |
+ ~ limitations under the License. |
|
| 16 |
+ --> |
|
| 17 |
+ |
|
| 18 |
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 19 |
+ <background android:drawable="@color/ic_logo_background"/> |
|
| 20 |
+ <foreground android:drawable="@drawable/ic_logo_foreground"/> |
|
| 21 |
+ <monochrome android:drawable="@drawable/ic_logo" /> |
|
| 22 |
+</adaptive-icon> |
|
| 0 | 23 |
\ No newline at end of file |
| 21 | 44 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,133 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<navigation xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto" |
|
| 19 |
+ xmlns:tools="http://schemas.android.com/tools" |
|
| 20 |
+ android:id="@+id/navigation" |
|
| 21 |
+ app:startDestination="@id/onboardingFragment"> |
|
| 22 |
+ |
|
| 23 |
+ <fragment |
|
| 24 |
+ android:id="@+id/homeFragment" |
|
| 25 |
+ android:name="com.certified.audionote.ui.HomeFragment" |
|
| 26 |
+ android:label="HomeFragment" |
|
| 27 |
+ tools:layout="@layout/fragment_home"> |
|
| 28 |
+ <action |
|
| 29 |
+ android:id="@+id/action_homeFragment_to_editNoteFragment" |
|
| 30 |
+ app:destination="@id/editNoteFragment" |
|
| 31 |
+ app:enterAnim="@anim/slide_in" |
|
| 32 |
+ app:exitAnim="@anim/fade_out" |
|
| 33 |
+ app:popEnterAnim="@anim/fade_in" |
|
| 34 |
+ app:popExitAnim="@anim/slide_out" |
|
| 35 |
+ app:popUpTo="@id/homeFragment" |
|
| 36 |
+ app:popUpToInclusive="false" /> |
|
| 37 |
+ <action |
|
| 38 |
+ android:id="@+id/action_homeFragment_to_addNoteFragment" |
|
| 39 |
+ app:destination="@id/addNoteFragment" |
|
| 40 |
+ app:enterAnim="@anim/slide_in" |
|
| 41 |
+ app:exitAnim="@anim/fade_out" |
|
| 42 |
+ app:popEnterAnim="@anim/fade_in" |
|
| 43 |
+ app:popExitAnim="@anim/slide_out" |
|
| 44 |
+ app:popUpTo="@id/homeFragment" |
|
| 45 |
+ app:popUpToInclusive="false" /> |
|
| 46 |
+ <action |
|
| 47 |
+ android:id="@+id/action_homeFragment_to_settingsFragment" |
|
| 48 |
+ app:destination="@id/settingsFragment" |
|
| 49 |
+ app:enterAnim="@anim/slide_in" |
|
| 50 |
+ app:exitAnim="@anim/fade_out" |
|
| 51 |
+ app:popEnterAnim="@anim/fade_in" |
|
| 52 |
+ app:popExitAnim="@anim/slide_out" |
|
| 53 |
+ app:popUpTo="@id/homeFragment" |
|
| 54 |
+ app:popUpToInclusive="false" /> |
|
| 55 |
+ </fragment> |
|
| 56 |
+ <fragment |
|
| 57 |
+ android:id="@+id/editNoteFragment" |
|
| 58 |
+ android:name="com.certified.audionote.ui.EditNoteFragment" |
|
| 59 |
+ android:label="EditNoteFragment" |
|
| 60 |
+ tools:layout="@layout/fragment_edit_note"> |
|
| 61 |
+ <action |
|
| 62 |
+ android:id="@+id/action_editNoteFragment_to_homeFragment" |
|
| 63 |
+ app:destination="@id/homeFragment" |
|
| 64 |
+ app:enterAnim="@anim/fade_in" |
|
| 65 |
+ app:exitAnim="@anim/slide_out" |
|
| 66 |
+ app:popUpTo="@id/homeFragment" |
|
| 67 |
+ app:popUpToInclusive="false" /> |
|
| 68 |
+ <argument |
|
| 69 |
+ android:name="note" |
|
| 70 |
+ app:argType="com.certified.audionote.model.Note" /> |
|
| 71 |
+ </fragment> |
|
| 72 |
+ <fragment |
|
| 73 |
+ android:id="@+id/addNoteFragment" |
|
| 74 |
+ android:name="com.certified.audionote.ui.AddNoteFragment" |
|
| 75 |
+ android:label="AddNoteFragment" |
|
| 76 |
+ tools:layout="@layout/fragment_add_note"> |
|
| 77 |
+ <action |
|
| 78 |
+ android:id="@+id/action_addNoteFragment_to_homeFragment" |
|
| 79 |
+ app:destination="@id/homeFragment" |
|
| 80 |
+ app:enterAnim="@anim/fade_in" |
|
| 81 |
+ app:exitAnim="@anim/slide_out" |
|
| 82 |
+ app:popUpTo="@id/homeFragment" |
|
| 83 |
+ app:popUpToInclusive="false" /> |
|
| 84 |
+ <argument |
|
| 85 |
+ android:name="note" |
|
| 86 |
+ app:argType="com.certified.audionote.model.Note" /> |
|
| 87 |
+ </fragment> |
|
| 88 |
+ <fragment |
|
| 89 |
+ android:id="@+id/settingsFragment" |
|
| 90 |
+ android:name="com.certified.audionote.features.settings.SettingsFragment" |
|
| 91 |
+ android:label="SettingsFragment" |
|
| 92 |
+ tools:layout="@layout/fragment_settings"> |
|
| 93 |
+ <action |
|
| 94 |
+ android:id="@+id/action_settingsFragment_to_homeFragment" |
|
| 95 |
+ app:destination="@id/homeFragment" |
|
| 96 |
+ app:enterAnim="@anim/fade_in" |
|
| 97 |
+ app:exitAnim="@anim/slide_out" |
|
| 98 |
+ app:popUpTo="@id/homeFragment" |
|
| 99 |
+ app:popUpToInclusive="true" /> |
|
| 100 |
+ <action |
|
| 101 |
+ android:id="@+id/action_settingsFragment_to_aboutFragment" |
|
| 102 |
+ app:destination="@id/aboutFragment" |
|
| 103 |
+ app:enterAnim="@anim/slide_in" |
|
| 104 |
+ app:exitAnim="@anim/fade_out" |
|
| 105 |
+ app:popEnterAnim="@anim/fade_in" |
|
| 106 |
+ app:popExitAnim="@anim/slide_out" |
|
| 107 |
+ app:popUpTo="@id/settingsFragment" /> |
|
| 108 |
+ </fragment> |
|
| 109 |
+ <fragment |
|
| 110 |
+ android:id="@+id/aboutFragment" |
|
| 111 |
+ android:name="com.certified.audionote.ui.AboutFragment" |
|
| 112 |
+ android:label="fragment_about" |
|
| 113 |
+ tools:layout="@layout/fragment_about"> |
|
| 114 |
+ <action |
|
| 115 |
+ android:id="@+id/action_aboutFragment_to_settingsFragment" |
|
| 116 |
+ app:destination="@id/settingsFragment" |
|
| 117 |
+ app:enterAnim="@anim/fade_in" |
|
| 118 |
+ app:exitAnim="@anim/slide_out" |
|
| 119 |
+ app:popUpTo="@id/settingsFragment" |
|
| 120 |
+ app:popUpToInclusive="true" /> |
|
| 121 |
+ </fragment> |
|
| 122 |
+ <fragment |
|
| 123 |
+ android:id="@+id/onboardingFragment" |
|
| 124 |
+ android:name="com.certified.audionote.ui.OnboardingFragment" |
|
| 125 |
+ android:label="fragment_onboarding" |
|
| 126 |
+ tools:layout="@layout/fragment_onboarding" > |
|
| 127 |
+ <action |
|
| 128 |
+ android:id="@+id/action_onboardingFragment_to_homeFragment" |
|
| 129 |
+ app:destination="@id/homeFragment" |
|
| 130 |
+ app:popUpTo="@id/navigation" |
|
| 131 |
+ app:popUpToInclusive="true" /> |
|
| 132 |
+ </fragment> |
|
| 133 |
+</navigation> |
|
| 0 | 134 |
\ No newline at end of file |
| 1 | 135 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,86 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<resources> |
|
| 18 |
+ <string name="app_name">Audio Notes</string> |
|
| 19 |
+ <string name="display">Visualizzazione</string> |
|
| 20 |
+ <string name="theme">Tema</string> |
|
| 21 |
+ <string name="choose_theme">Scegli tema</string> |
|
| 22 |
+ <string name="description">Descrizione</string> |
|
| 23 |
+ <string name="note_title_required">Titolo della nota (obbligatorio)</string> |
|
| 24 |
+ <string name="new_note">Nuova Nota</string> |
|
| 25 |
+ <string name="save">Salva</string> |
|
| 26 |
+ <string name="add_note_button">Pulsante Aggiungi nota</string> |
|
| 27 |
+ <string name="back_button">Pulsante Indietro</string> |
|
| 28 |
+ <string name="delete_button">Pulsante Elimina</string> |
|
| 29 |
+ <string name="share_button">Pulsante Condividi</string> |
|
| 30 |
+ <string name="click_to_add_a_reminder_to_this_note">Aggiungi un promemoria a questa nota</string> |
|
| 31 |
+ <string name="record_button">Registra</string> |
|
| 32 |
+ <string name="reminder_button">Pulsante Promemoria</string> |
|
| 33 |
+ <string name="welcome_back">Bentornato</string> |
|
| 34 |
+ <string name="hi_there">Ehilà,</string> |
|
| 35 |
+ <string name="your_record_list_is_empty_click_the_button_below_to_get_started">L\'elenco delle registrazioni è vuoto. Clicca sul pulsante in basso per iniziare</string> |
|
| 36 |
+ <string name="about">Informazioni</string> |
|
| 37 |
+ <string name="attributions_amp_licence">Attribuzioni e Licenze</string> |
|
| 38 |
+ <string name="licenced_under_apache_licence_version_2_0">Rilasciato sotto Licenza Apache, Versione 2.0</string> |
|
| 39 |
+ <string name="app_version_licence_and_more">Versione dell\'app, licenza e altro</string> |
|
| 40 |
+ <string name="settings">Impostazioni</string> |
|
| 41 |
+ <string name="edit_note">Modifica Nota</string> |
|
| 42 |
+ <string name="alarm_icon">Icona Sveglia</string> |
|
| 43 |
+ <string name="modify">Modifica</string> |
|
| 44 |
+ <string name="delete">Elimina</string> |
|
| 45 |
+ <string name="no_reminder_set">Nessun promemoria</string> |
|
| 46 |
+ <string name="channelId">Notifica di Audio Notes</string> |
|
| 47 |
+ <string name="view_pager_title_audio_recording">Registra audio facilmente</string> |
|
| 48 |
+ <string name="view_pager_description_audio_recording">Prendere appunti non dovrebbe riguardare la digitazione o la scrittura da sole. Usa la funzione di registrazione vocale per registrare la tua nota in modo facile e veloce per migliorare la tua produttività</string> |
|
| 49 |
+ <string name="view_pager_title_notification">Notifiche Personalizzate</string> |
|
| 50 |
+ <string name="view_pager_description_notification">Imposta un promemoria per le tue note e ricevi una notifica all\'ora esatta per cui hai impostato il promemoria. Non devi più preoccuparti di dimenticare di controllare una nota.</string> |
|
| 51 |
+ <string name="view_pager_title_dark_mode">Progettato per te</string> |
|
| 52 |
+ <string name="view_pager_description_dark_mode">Prendere appunti non dovrebbe essere fantascienza. L\'app è stata progettata pensando a te per facilitare il modo in cui prendi appunti e anche per migliorare la tua produttività</string> |
|
| 53 |
+ <string name="record_player">Registratore</string> |
|
| 54 |
+ <string name="developer">Sviluppatore</string> |
|
| 55 |
+ <string name="contribute">Contribuisci</string> |
|
| 56 |
+ <string name="contribute_summary">Visualizza il progetto su GitHub</string> |
|
| 57 |
+ <string name="contact_feedback">Contatto e Feedback</string> |
|
| 58 |
+ <string name="get_started">Iniziamo</string> |
|
| 59 |
+ <string name="just_now">Proprio ora</string> |
|
| 60 |
+ <string name="a_minute_ago">un minuto fa</string> |
|
| 61 |
+ <string name="minutes_ago">minuti fa</string> |
|
| 62 |
+ <string name="an_hour_ago">un\'ora fa</string> |
|
| 63 |
+ <string name="hours_ago">ore fa</string> |
|
| 64 |
+ <string name="a_day_ago">un giorno fa</string> |
|
| 65 |
+ <string name="theme_system_default">Predefinito di sistema</string> |
|
| 66 |
+ <string name="theme_light">Chiaro</string> |
|
| 67 |
+ <string name="theme_dark">Scuro</string> |
|
| 68 |
+ <string name="now_playing">In riproduzione</string> |
|
| 69 |
+ <string name="title_required">Il titolo della nota è obbligatorio</string> |
|
| 70 |
+ <string name="permission_required">Questa autorizzazione è richiesta per abilitare le registrazioni audio</string> |
|
| 71 |
+ <string name="note_saved">Nota salvata</string> |
|
| 72 |
+ <string name="started_recording">Registrazione avviata</string> |
|
| 73 |
+ <string name="stopped_recording">Registrazione terminata</string> |
|
| 74 |
+ <string name="started_playing_recording">Riproduzione della registrazione avviata</string> |
|
| 75 |
+ <string name="stopped_playing_recording">Riproduzione della registrazione terminata</string> |
|
| 76 |
+ <string name="error_occurred">Si è verificato un errore</string> |
|
| 77 |
+ <string name="yes">Sì</string> |
|
| 78 |
+ <string name="no">No</string> |
|
| 79 |
+ <string name="delete_note">Elimina Nota</string> |
|
| 80 |
+ <string name="confirm_deletion">Sei sicuro di voler eliminare</string> |
|
| 81 |
+ <string name="all">Tutte</string> |
|
| 82 |
+ <string name="today">Oggi</string> |
|
| 83 |
+ <string name="upcoming">Imminenti</string> |
|
| 84 |
+ <string name="completed">Completate</string> |
|
| 85 |
+ <string name="record_note_before_saving">Registra la tua nota audio prima di salvare</string> |
|
| 86 |
+</resources> |
|
| 0 | 87 |
\ No newline at end of file |
| 1 | 88 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<resources> |
|
| 18 |
+ <integer name="span_count">3</integer> |
|
| 19 |
+</resources> |
|
| 20 |
+ |
|
| 21 |
+ <!-- todo create ui constants for different screen sizes --> |
|
| 0 | 22 |
\ No newline at end of file |
| 1 | 23 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<resources> |
|
| 18 |
+ <integer name="span_count">3</integer> |
|
| 19 |
+</resources> |
|
| 20 |
+ |
|
| 21 |
+ <!-- todo create ui constants for different screen sizes --> |
|
| 0 | 22 |
\ No newline at end of file |
| 1 | 23 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,41 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
+<!-- |
|
| 3 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 4 |
+ ~ |
|
| 5 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ ~ you may not use this file except in compliance with the License. |
|
| 7 |
+ ~ You may obtain a copy of the License at |
|
| 8 |
+ ~ |
|
| 9 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ ~ |
|
| 11 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ ~ See the License for the specific language governing permissions and |
|
| 15 |
+ ~ limitations under the License. |
|
| 16 |
+ --> |
|
| 17 |
+ |
|
| 18 |
+<resources> |
|
| 19 |
+ <color name="purple_200">#FFBB86FC</color> |
|
| 20 |
+ <color name="purple_500">#FF6200EE</color> |
|
| 21 |
+ <color name="purple_700">#FF3700B3</color> |
|
| 22 |
+ <color name="teal_200">#FF03DAC5</color> |
|
| 23 |
+ <color name="teal_700">#FF018786</color> |
|
| 24 |
+ <color name="black">#FF000000</color> |
|
| 25 |
+ <color name="white">#FFFFFFFF</color> |
|
| 26 |
+ |
|
| 27 |
+ <color name="black_day_white_night">@color/white</color> |
|
| 28 |
+ <color name="fragment_background">@color/primary</color> |
|
| 29 |
+ <color name="other_fragment_background">@color/primary_darker</color> |
|
| 30 |
+ <color name="primary">#313033</color> |
|
| 31 |
+ <color name="primary_dark">#1C1B1F</color> |
|
| 32 |
+ <color name="primary_darker">@color/black</color> |
|
| 33 |
+ <color name="accent">@color/white</color> |
|
| 34 |
+ <color name="mic_accent">#939094</color> |
|
| 35 |
+ <color name="fab_background_tint">#EFB8C8</color> |
|
| 36 |
+ <color name="about_icon_color">#939094</color> |
|
| 37 |
+ <color name="edit_reminder_button_color">@color/about_icon_color</color> |
|
| 38 |
+ <color name="grey">@color/white</color> |
|
| 39 |
+ <color name="titleText">@color/white</color> |
|
| 40 |
+ <color name="subtitleText">@color/white</color> |
|
| 41 |
+</resources> |
|
| 0 | 42 |
\ No newline at end of file |
| 1 | 43 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<resources xmlns:tools="http://schemas.android.com/tools"> |
|
| 18 |
+ <!-- Base application theme. --> |
|
| 19 |
+ <style name="Theme.AudioNote" parent="Theme.MaterialComponents.DayNight.NoActionBar"> |
|
| 20 |
+ <!-- Primary brand color. --> |
|
| 21 |
+ <item name="colorPrimary">@color/primary</item> |
|
| 22 |
+ <item name="colorPrimaryVariant">@color/primary_dark</item> |
|
| 23 |
+ <item name="colorOnPrimary">@color/accent</item> |
|
| 24 |
+ <!-- Secondary brand color. --> |
|
| 25 |
+ <item name="colorSecondary">#D29DAC</item> |
|
| 26 |
+ <item name="colorSecondaryVariant">@color/teal_200</item> |
|
| 27 |
+ <item name="colorOnSecondary">@color/black</item> |
|
| 28 |
+ <!-- Status bar color. --> |
|
| 29 |
+ <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> |
|
| 30 |
+ <!-- Customize your theme here. --> |
|
| 31 |
+ <!-- <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>--> |
|
| 32 |
+ </style> |
|
| 33 |
+</resources> |
|
| 0 | 34 |
\ No newline at end of file |
| 1 | 35 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,37 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<resources> |
|
| 18 |
+ <!-- Theme Preference --> |
|
| 19 |
+ <string-array name="pref_theme"> |
|
| 20 |
+ <item>@string/theme_system_default</item> |
|
| 21 |
+ <item>@string/theme_light</item> |
|
| 22 |
+ <item>@string/theme_dark</item> |
|
| 23 |
+ </string-array> |
|
| 24 |
+ |
|
| 25 |
+ <string-array name="pref_theme_values"> |
|
| 26 |
+ <item>MODE_NIGHT_FOLLOW_SYSTEM</item> |
|
| 27 |
+ <item>MODE_NIGHT_NO</item> |
|
| 28 |
+ <item>MODE_NIGHT_YES</item> |
|
| 29 |
+ </string-array> |
|
| 30 |
+ |
|
| 31 |
+ <string-array name="filter_array"> |
|
| 32 |
+ <item>@string/all</item> |
|
| 33 |
+ <item>@string/today</item> |
|
| 34 |
+ <item>@string/upcoming</item> |
|
| 35 |
+ <item>@string/completed</item> |
|
| 36 |
+ </string-array> |
|
| 37 |
+</resources> |
|
| 0 | 38 |
\ No newline at end of file |
| 1 | 39 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,41 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
+<!-- |
|
| 3 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 4 |
+ ~ |
|
| 5 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ ~ you may not use this file except in compliance with the License. |
|
| 7 |
+ ~ You may obtain a copy of the License at |
|
| 8 |
+ ~ |
|
| 9 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ ~ |
|
| 11 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ ~ See the License for the specific language governing permissions and |
|
| 15 |
+ ~ limitations under the License. |
|
| 16 |
+ --> |
|
| 17 |
+ |
|
| 18 |
+<resources> |
|
| 19 |
+ <color name="purple_200">#FFBB86FC</color> |
|
| 20 |
+ <color name="purple_500">#FF6200EE</color> |
|
| 21 |
+ <color name="purple_700">#FF3700B3</color> |
|
| 22 |
+ <color name="teal_200">#FF03DAC5</color> |
|
| 23 |
+ <color name="teal_700">#FF018786</color> |
|
| 24 |
+ <color name="black">#FF000000</color> |
|
| 25 |
+ <color name="white">#FFFFFFFF</color> |
|
| 26 |
+ |
|
| 27 |
+ <color name="black_day_white_night">@color/black</color> |
|
| 28 |
+ <color name="fragment_background">@color/accent</color> |
|
| 29 |
+ <color name="other_fragment_background">@color/primary_darker</color> |
|
| 30 |
+ <color name="primary">#EFB8C8</color> |
|
| 31 |
+ <color name="primary_dark">#D29DAC</color> |
|
| 32 |
+ <color name="primary_darker">#986977</color> |
|
| 33 |
+ <color name="accent">#FFECF1</color> |
|
| 34 |
+ <color name="mic_accent">#939094</color> |
|
| 35 |
+ <color name="fab_background_tint">@color/primary</color> |
|
| 36 |
+ <color name="about_icon_color">#EFB8C8</color> |
|
| 37 |
+ <color name="edit_reminder_button_color">@color/other_fragment_background</color> |
|
| 38 |
+ <color name="grey">#AEAEAE</color> |
|
| 39 |
+ <color name="titleText">@color/primary_darker</color> |
|
| 40 |
+ <color name="subtitleText">@color/primary_dark</color> |
|
| 41 |
+</resources> |
|
| 0 | 42 |
\ No newline at end of file |
| 1 | 43 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,20 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
+<!-- |
|
| 3 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 4 |
+ ~ |
|
| 5 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ ~ you may not use this file except in compliance with the License. |
|
| 7 |
+ ~ You may obtain a copy of the License at |
|
| 8 |
+ ~ |
|
| 9 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ ~ |
|
| 11 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ ~ See the License for the specific language governing permissions and |
|
| 15 |
+ ~ limitations under the License. |
|
| 16 |
+ --> |
|
| 17 |
+ |
|
| 18 |
+<resources> |
|
| 19 |
+ <color name="ic_logo_background">@color/primary</color> |
|
| 20 |
+</resources> |
|
| 0 | 21 |
\ No newline at end of file |
| 1 | 22 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,98 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<resources> |
|
| 18 |
+ <string name="app_name">Audio Notes</string> |
|
| 19 |
+ <string name="display">Display</string> |
|
| 20 |
+ <string name="theme">Theme</string> |
|
| 21 |
+ <string name="default_theme" translatable="false">MODE_NIGHT_FOLLOW_SYSTEM</string> |
|
| 22 |
+ <string name="choose_theme">Choose theme</string> |
|
| 23 |
+ <string name="key_theme" translatable="false">theme</string> |
|
| 24 |
+ <string name="description">Description</string> |
|
| 25 |
+ <string name="note_title_required">Note title (required)</string> |
|
| 26 |
+ <string name="new_note">New Note</string> |
|
| 27 |
+ <string name="save">Save</string> |
|
| 28 |
+ <string name="add_note_button">Add note button</string> |
|
| 29 |
+ <string name="back_button">Back button</string> |
|
| 30 |
+ <string name="delete_button">Delete button</string> |
|
| 31 |
+ <string name="share_button">Share button</string> |
|
| 32 |
+ <string name="click_to_add_a_reminder_to_this_note">Click to add a reminder to this note</string> |
|
| 33 |
+ <string name="record_button">Record</string> |
|
| 34 |
+ <string name="reminder_button">Reminder button</string> |
|
| 35 |
+ <string name="welcome_back">Welcome back</string> |
|
| 36 |
+ <string name="hi_there">Hi there,</string> |
|
| 37 |
+ <string name="your_record_list_is_empty_click_the_button_below_to_get_started">Your record list is empty. Click the button below to get started</string> |
|
| 38 |
+ <string name="about">About</string> |
|
| 39 |
+ <string name="app_version" translatable="false">v0.1.5.2(02052023)</string> |
|
| 40 |
+ <string name="attributions_amp_licence"><![CDATA[Attributions & Licence]]></string> |
|
| 41 |
+ <string name="licenced_under_apache_licence_version_2_0">Licenced under Apache Licence, Version 2.0</string> |
|
| 42 |
+ <string name="app_version_licence_and_more">App version, Licence and more</string> |
|
| 43 |
+ <string name="settings">Settings</string> |
|
| 44 |
+ <string name="edit_note">Edit Note</string> |
|
| 45 |
+ <string name="alarm_icon">Alarm Icon</string> |
|
| 46 |
+ <string name="modify">Modify</string> |
|
| 47 |
+ <string name="delete">Delete</string> |
|
| 48 |
+ <string name="no_reminder_set">No reminder set</string> |
|
| 49 |
+ <string name="channelId">Audio Notes notification</string> |
|
| 50 |
+ <string name="view_pager_title_audio_recording">Record audio easily</string> |
|
| 51 |
+ <string name="view_pager_description_audio_recording">Taking notes shouldn\'t be about typing or writing alone. Use the voice recording feature to record your note easily and faster to improve your productivity</string> |
|
| 52 |
+ <string name="view_pager_title_notification">Custom Notifications</string> |
|
| 53 |
+ <string name="view_pager_description_notification">Set a reminder for your notes and get notified at the exact time you set the reminder for. You no longer have to worry about forgetting to check out a note.</string> |
|
| 54 |
+ <string name="view_pager_title_dark_mode">Designed for you</string> |
|
| 55 |
+ <string name="view_pager_description_dark_mode">Taking notes shouldn\'t be rocket science. The application was designed with you in mind to ease how you take notes and to also improve your productivity</string> |
|
| 56 |
+ <string name="record_player">Record Player</string> |
|
| 57 |
+ <string name="developer">Developer</string> |
|
| 58 |
+ <string name="developer_nick" translatable="false">Sammie_kt</string> |
|
| 59 |
+ <string name="contribute">Contribute</string> |
|
| 60 |
+ <string name="contribute_summary">View project on Github</string> |
|
| 61 |
+ <string name="developer_mail" translatable="false">Sammie_kt@pm.me</string> |
|
| 62 |
+ <string name="contact_feedback"><![CDATA[Contact & Feedback]]></string> |
|
| 63 |
+ <string name="get_started">Get Started</string> |
|
| 64 |
+ <string name="just_now">Just now</string> |
|
| 65 |
+ <string name="a_minute_ago">a minute ago</string> |
|
| 66 |
+ <string name="minutes_ago">minutes ago</string> |
|
| 67 |
+ <string name="an_hour_ago">an hour ago</string> |
|
| 68 |
+ <string name="hours_ago">hours ago</string> |
|
| 69 |
+ <string name="a_day_ago">a day ago</string> |
|
| 70 |
+ <string name="theme_system_default">System default</string> |
|
| 71 |
+ <string name="theme_light">Light</string> |
|
| 72 |
+ <string name="theme_dark">Dark</string> |
|
| 73 |
+ <string name="now_playing">Now playing</string> |
|
| 74 |
+ <string name="title_required">The note title is required</string> |
|
| 75 |
+ <string name="permission_required">This permission is required to enable audio recording</string> |
|
| 76 |
+ <string name="note_saved">Note saved</string> |
|
| 77 |
+ <string name="started_recording">Started recording</string> |
|
| 78 |
+ <string name="stopped_recording">Stopped recording</string> |
|
| 79 |
+ <string name="started_playing_recording">Started playing recording</string> |
|
| 80 |
+ <string name="stopped_playing_recording">Stopped playing recording</string> |
|
| 81 |
+ <string name="error_occurred">An error occurred</string> |
|
| 82 |
+ <string name="yes">Yes</string> |
|
| 83 |
+ <string name="no">No</string> |
|
| 84 |
+ <string name="delete_note">Delete Note</string> |
|
| 85 |
+ <string name="confirm_deletion">Are you sure you want to delete</string> |
|
| 86 |
+ <string name="all">All</string> |
|
| 87 |
+ <string name="today">Today</string> |
|
| 88 |
+ <string name="upcoming">Upcoming</string> |
|
| 89 |
+ <string name="completed">Completed</string> |
|
| 90 |
+ <string name="record_note_before_saving">Please record your audio note before saving</string> |
|
| 91 |
+ <string name="notification_permission_required" translatable="false">Notification permission is required to ensure you receive reminders for your saved notes</string> |
|
| 92 |
+ <string name="notification_permission" translatable="false">Notification Permission</string> |
|
| 93 |
+ <string name="audio_notes_channel" translatable="false">Audio Notes channel</string> |
|
| 94 |
+ <string name="audio_record_permission" translatable="false">Audio record permission</string> |
|
| 95 |
+ <string name="ok" translatable="false">OK</string> |
|
| 96 |
+ <string name="file_not_found" translatable="false">File not found</string> |
|
| 97 |
+ <string name="info_icon">Info Icon</string> |
|
| 98 |
+</resources> |
|
| 0 | 99 |
\ No newline at end of file |
| 1 | 100 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,38 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<resources xmlns:tools="http://schemas.android.com/tools"> |
|
| 18 |
+ <!-- Base application theme. --> |
|
| 19 |
+ <style name="Theme.AudioNote" parent="Theme.MaterialComponents.DayNight.NoActionBar"> |
|
| 20 |
+ <!-- Primary brand color. --> |
|
| 21 |
+ <item name="colorPrimary">@color/primary</item> |
|
| 22 |
+ <item name="colorPrimaryVariant">@color/primary_dark</item> |
|
| 23 |
+ <item name="colorOnPrimary">@color/accent</item> |
|
| 24 |
+ <!-- Secondary brand color. --> |
|
| 25 |
+ <item name="colorSecondary">@color/primary_dark</item> |
|
| 26 |
+ <item name="colorSecondaryVariant">@color/teal_700</item> |
|
| 27 |
+ <item name="colorOnSecondary">@color/black</item> |
|
| 28 |
+ <!-- Status bar color. --> |
|
| 29 |
+ <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> |
|
| 30 |
+ <!-- Customize your theme here. --> |
|
| 31 |
+<!-- <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>--> |
|
| 32 |
+ </style> |
|
| 33 |
+ |
|
| 34 |
+ <style name="ShapeAppearanceOverlay.AudioNotes" parent=""> |
|
| 35 |
+ <item name="cornerSize">15%</item> |
|
| 36 |
+ </style> |
|
| 37 |
+ |
|
| 38 |
+</resources> |
|
| 0 | 39 |
\ No newline at end of file |
| 1 | 40 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?><!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<resources> |
|
| 18 |
+ <integer name="span_count">2</integer> |
|
| 19 |
+</resources> |
|
| 20 |
+ |
|
| 21 |
+ <!-- todo create ui constants for different screen sizes --> |
|
| 0 | 22 |
\ No newline at end of file |
| 1 | 23 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,20 @@ |
| 1 |
+<?xml version="1.0" encoding="utf-8"?> |
|
| 2 |
+<!-- |
|
| 3 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 4 |
+ ~ |
|
| 5 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ ~ you may not use this file except in compliance with the License. |
|
| 7 |
+ ~ You may obtain a copy of the License at |
|
| 8 |
+ ~ |
|
| 9 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ ~ |
|
| 11 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ ~ See the License for the specific language governing permissions and |
|
| 15 |
+ ~ limitations under the License. |
|
| 16 |
+ --> |
|
| 17 |
+ |
|
| 18 |
+<paths xmlns:android="http://schemas.android.com/apk/res/android"> |
|
| 19 |
+ <external-path name="recordings" path="/" /> |
|
| 20 |
+</paths> |
|
| 0 | 21 |
\ No newline at end of file |
| 1 | 22 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,72 @@ |
| 1 |
+<!-- |
|
| 2 |
+ ~ Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ ~ |
|
| 4 |
+ ~ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ ~ you may not use this file except in compliance with the License. |
|
| 6 |
+ ~ You may obtain a copy of the License at |
|
| 7 |
+ ~ |
|
| 8 |
+ ~ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ ~ |
|
| 10 |
+ ~ Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ ~ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ ~ See the License for the specific language governing permissions and |
|
| 14 |
+ ~ limitations under the License. |
|
| 15 |
+ --> |
|
| 16 |
+ |
|
| 17 |
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" |
|
| 18 |
+ xmlns:app="http://schemas.android.com/apk/res-auto"> |
|
| 19 |
+ |
|
| 20 |
+ <PreferenceCategory app:title="@string/display"> |
|
| 21 |
+ |
|
| 22 |
+ <ListPreference |
|
| 23 |
+ app:defaultValue="@string/default_theme" |
|
| 24 |
+ app:dialogTitle="@string/choose_theme" |
|
| 25 |
+ app:entries="@array/pref_theme" |
|
| 26 |
+ app:entryValues="@array/pref_theme_values" |
|
| 27 |
+ app:icon="@drawable/ic_brightness_medium_black_24dp" |
|
| 28 |
+ app:key="@string/key_theme" |
|
| 29 |
+ app:title="@string/theme" |
|
| 30 |
+ app:useSimpleSummaryProvider="true" /> |
|
| 31 |
+ |
|
| 32 |
+ </PreferenceCategory> |
|
| 33 |
+ |
|
| 34 |
+ <PreferenceCategory app:title="@string/about"> |
|
| 35 |
+ <Preference |
|
| 36 |
+ android:icon="@drawable/ic_person_black_24" |
|
| 37 |
+ app:summary="@string/developer_nick" |
|
| 38 |
+ app:title="@string/developer"> |
|
| 39 |
+ <intent |
|
| 40 |
+ android:action="android.intent.action.VIEW" |
|
| 41 |
+ android:data="https://github.com/certified84" /> |
|
| 42 |
+ </Preference> |
|
| 43 |
+ |
|
| 44 |
+ <Preference |
|
| 45 |
+ android:icon="@drawable/ic_code_black_24dp" |
|
| 46 |
+ app:summary="@string/contribute_summary" |
|
| 47 |
+ app:title="@string/contribute"> |
|
| 48 |
+ <intent |
|
| 49 |
+ android:action="android.intent.action.VIEW" |
|
| 50 |
+ android:data="https://github.com/certified84/AudioNote" /> |
|
| 51 |
+ </Preference> |
|
| 52 |
+ |
|
| 53 |
+ <Preference |
|
| 54 |
+ android:icon="@drawable/ic_contact_support_black_24dp" |
|
| 55 |
+ app:summary="@string/developer_mail" |
|
| 56 |
+ app:title="@string/contact_feedback"> |
|
| 57 |
+ <intent |
|
| 58 |
+ android:action="android.intent.action.SENDTO" |
|
| 59 |
+ android:data="mailto:Sammie_kt@pm.me?subject=Feedback" /> |
|
| 60 |
+ </Preference> |
|
| 61 |
+ |
|
| 62 |
+<!-- <Preference--> |
|
| 63 |
+<!-- android:icon="@drawable/ic_info_black_24dp"--> |
|
| 64 |
+<!-- app:summary="@string/app_version_licence_and_more"--> |
|
| 65 |
+<!-- app:title="@string/about">--> |
|
| 66 |
+<!-- <intent--> |
|
| 67 |
+<!-- android:action="android.intent.action.VIEW"--> |
|
| 68 |
+<!-- android:data="https://github.com/certified84/AudioNote" />--> |
|
| 69 |
+<!-- </Preference>--> |
|
| 70 |
+ </PreferenceCategory> |
|
| 71 |
+ |
|
| 72 |
+</PreferenceScreen> |
|
| 0 | 73 |
\ No newline at end of file |
| 1 | 74 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+package com.certified.audionote |
|
| 18 |
+ |
|
| 19 |
+import org.junit.Test |
|
| 20 |
+ |
|
| 21 |
+import org.junit.Assert.* |
|
| 22 |
+ |
|
| 23 |
+/** |
|
| 24 |
+ * Example local unit test, which will execute on the development machine (host). |
|
| 25 |
+ * |
|
| 26 |
+ * See [testing documentation](http://d.android.com/tools/testing). |
|
| 27 |
+ */ |
|
| 28 |
+class ExampleUnitTest {
|
|
| 29 |
+ @Test |
|
| 30 |
+ fun addition_isCorrect() {
|
|
| 31 |
+ assertEquals(4, 2 + 2) |
|
| 32 |
+ } |
|
| 33 |
+} |
|
| 0 | 34 |
\ No newline at end of file |
| 1 | 35 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,49 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+plugins{
|
|
| 18 |
+ id("com.google.devtools.ksp") version "2.1.0-1.0.29" apply false
|
|
| 19 |
+} |
|
| 20 |
+ |
|
| 21 |
+// Top-level build file where you can add configuration options common to all sub-projects/modules. |
|
| 22 |
+buildscript {
|
|
| 23 |
+ repositories {
|
|
| 24 |
+ google() |
|
| 25 |
+ mavenCentral() |
|
| 26 |
+ maven {url = uri("https://maven.google.com")}
|
|
| 27 |
+ maven { url = uri("https://jitpack.io") }
|
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ dependencies {
|
|
| 31 |
+ classpath ("com.android.tools.build:gradle:8.7.3")
|
|
| 32 |
+ classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0")
|
|
| 33 |
+ classpath ("androidx.navigation:navigation-safe-args-gradle-plugin:2.8.5")
|
|
| 34 |
+ classpath ("com.google.dagger:hilt-android-gradle-plugin:2.53.1")
|
|
| 35 |
+ classpath("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
|
|
| 36 |
+ |
|
| 37 |
+ // NOTE: Do not place your application dependencies here; they belong |
|
| 38 |
+ // in the individual module build.gradle files |
|
| 39 |
+ } |
|
| 40 |
+} |
|
| 41 |
+ |
|
| 42 |
+allprojects {
|
|
| 43 |
+ repositories {
|
|
| 44 |
+ google() |
|
| 45 |
+ mavenCentral() |
|
| 46 |
+ maven {url = uri("https://maven.google.com")}
|
|
| 47 |
+ maven { url = uri("https://jitpack.io") }
|
|
| 48 |
+ } |
|
| 49 |
+} |
|
| 0 | 50 |
\ No newline at end of file |
| 1 | 3 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,39 @@ |
| 1 |
+# |
|
| 2 |
+# Copyright (c) 2023 Samson Achiaga |
|
| 3 |
+# |
|
| 4 |
+# Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+# you may not use this file except in compliance with the License. |
|
| 6 |
+# You may obtain a copy of the License at |
|
| 7 |
+# |
|
| 8 |
+# http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+# |
|
| 10 |
+# Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+# distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+# See the License for the specific language governing permissions and |
|
| 14 |
+# limitations under the License. |
|
| 15 |
+# |
|
| 16 |
+ |
|
| 17 |
+# Project-wide Gradle settings. |
|
| 18 |
+# IDE (e.g. Android Studio) users: |
|
| 19 |
+# Gradle settings configured through the IDE *will override* |
|
| 20 |
+# any settings specified in this file. |
|
| 21 |
+# For more details on how to configure your build environment visit |
|
| 22 |
+# http://www.gradle.org/docs/current/userguide/build_environment.html |
|
| 23 |
+# Specifies the JVM arguments used for the daemon process. |
|
| 24 |
+# The setting is particularly useful for tweaking memory settings. |
|
| 25 |
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 |
|
| 26 |
+# When configured, Gradle will run in incubating parallel mode. |
|
| 27 |
+# This option should only be used with decoupled projects. More details, visit |
|
| 28 |
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects |
|
| 29 |
+# org.gradle.parallel=true |
|
| 30 |
+# AndroidX package structure to make it clearer which packages are bundled with the |
|
| 31 |
+# Android operating system, and which are packaged with your app"s APK |
|
| 32 |
+# https://developer.android.com/topic/libraries/support-library/androidx-rn |
|
| 33 |
+android.useAndroidX=true |
|
| 34 |
+# Automatically convert third-party libraries to use AndroidX |
|
| 35 |
+android.enableJetifier=true |
|
| 36 |
+# Kotlin code style for this project: "official" or "obsolete": |
|
| 37 |
+kotlin.code.style=official |
|
| 38 |
+android.nonTransitiveRClass=false |
|
| 39 |
+android.nonFinalResIds=false |
|
| 0 | 40 |
\ No newline at end of file |
| 3 | 43 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,7 @@ |
| 1 |
+distributionBase=GRADLE_USER_HOME |
|
| 2 |
+distributionPath=wrapper/dists |
|
| 3 |
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip |
|
| 4 |
+networkTimeout=10000 |
|
| 5 |
+validateDistributionUrl=true |
|
| 6 |
+zipStoreBase=GRADLE_USER_HOME |
|
| 7 |
+zipStorePath=wrapper/dists |
| 0 | 8 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,249 @@ |
| 1 |
+#!/bin/sh |
|
| 2 |
+ |
|
| 3 |
+# |
|
| 4 |
+# Copyright © 2015-2021 the original authors. |
|
| 5 |
+# |
|
| 6 |
+# Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 7 |
+# you may not use this file except in compliance with the License. |
|
| 8 |
+# You may obtain a copy of the License at |
|
| 9 |
+# |
|
| 10 |
+# https://www.apache.org/licenses/LICENSE-2.0 |
|
| 11 |
+# |
|
| 12 |
+# Unless required by applicable law or agreed to in writing, software |
|
| 13 |
+# distributed under the License is distributed on an "AS IS" BASIS, |
|
| 14 |
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 15 |
+# See the License for the specific language governing permissions and |
|
| 16 |
+# limitations under the License. |
|
| 17 |
+# |
|
| 18 |
+ |
|
| 19 |
+############################################################################## |
|
| 20 |
+# |
|
| 21 |
+# Gradle start up script for POSIX generated by Gradle. |
|
| 22 |
+# |
|
| 23 |
+# Important for running: |
|
| 24 |
+# |
|
| 25 |
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is |
|
| 26 |
+# noncompliant, but you have some other compliant shell such as ksh or |
|
| 27 |
+# bash, then to run this script, type that shell name before the whole |
|
| 28 |
+# command line, like: |
|
| 29 |
+# |
|
| 30 |
+# ksh Gradle |
|
| 31 |
+# |
|
| 32 |
+# Busybox and similar reduced shells will NOT work, because this script |
|
| 33 |
+# requires all of these POSIX shell features: |
|
| 34 |
+# * functions; |
|
| 35 |
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
|
| 36 |
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
|
| 37 |
+# * compound commands having a testable exit status, especially «case»; |
|
| 38 |
+# * various built-in commands including «command», «set», and «ulimit». |
|
| 39 |
+# |
|
| 40 |
+# Important for patching: |
|
| 41 |
+# |
|
| 42 |
+# (2) This script targets any POSIX shell, so it avoids extensions provided |
|
| 43 |
+# by Bash, Ksh, etc; in particular arrays are avoided. |
|
| 44 |
+# |
|
| 45 |
+# The "traditional" practice of packing multiple parameters into a |
|
| 46 |
+# space-separated string is a well documented source of bugs and security |
|
| 47 |
+# problems, so this is (mostly) avoided, by progressively accumulating |
|
| 48 |
+# options in "$@", and eventually passing that to Java. |
|
| 49 |
+# |
|
| 50 |
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, |
|
| 51 |
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; |
|
| 52 |
+# see the in-line comments for details. |
|
| 53 |
+# |
|
| 54 |
+# There are tweaks for specific operating systems such as AIX, CygWin, |
|
| 55 |
+# Darwin, MinGW, and NonStop. |
|
| 56 |
+# |
|
| 57 |
+# (3) This script is generated from the Groovy template |
|
| 58 |
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt |
|
| 59 |
+# within the Gradle project. |
|
| 60 |
+# |
|
| 61 |
+# You can find Gradle at https://github.com/gradle/gradle/. |
|
| 62 |
+# |
|
| 63 |
+############################################################################## |
|
| 64 |
+ |
|
| 65 |
+# Attempt to set APP_HOME |
|
| 66 |
+ |
|
| 67 |
+# Resolve links: $0 may be a link |
|
| 68 |
+app_path=$0 |
|
| 69 |
+ |
|
| 70 |
+# Need this for daisy-chained symlinks. |
|
| 71 |
+while |
|
| 72 |
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
|
| 73 |
+ [ -h "$app_path" ] |
|
| 74 |
+do |
|
| 75 |
+ ls=$( ls -ld "$app_path" ) |
|
| 76 |
+ link=${ls#*' -> '}
|
|
| 77 |
+ case $link in #( |
|
| 78 |
+ /*) app_path=$link ;; #( |
|
| 79 |
+ *) app_path=$APP_HOME$link ;; |
|
| 80 |
+ esac |
|
| 81 |
+done |
|
| 82 |
+ |
|
| 83 |
+# This is normally unused |
|
| 84 |
+# shellcheck disable=SC2034 |
|
| 85 |
+APP_BASE_NAME=${0##*/}
|
|
| 86 |
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) |
|
| 87 |
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
|
| 88 |
+ |
|
| 89 |
+# Use the maximum available, or set MAX_FD != -1 to use that value. |
|
| 90 |
+MAX_FD=maximum |
|
| 91 |
+ |
|
| 92 |
+warn () {
|
|
| 93 |
+ echo "$*" |
|
| 94 |
+} >&2 |
|
| 95 |
+ |
|
| 96 |
+die () {
|
|
| 97 |
+ echo |
|
| 98 |
+ echo "$*" |
|
| 99 |
+ echo |
|
| 100 |
+ exit 1 |
|
| 101 |
+} >&2 |
|
| 102 |
+ |
|
| 103 |
+# OS specific support (must be 'true' or 'false'). |
|
| 104 |
+cygwin=false |
|
| 105 |
+msys=false |
|
| 106 |
+darwin=false |
|
| 107 |
+nonstop=false |
|
| 108 |
+case "$( uname )" in #( |
|
| 109 |
+ CYGWIN* ) cygwin=true ;; #( |
|
| 110 |
+ Darwin* ) darwin=true ;; #( |
|
| 111 |
+ MSYS* | MINGW* ) msys=true ;; #( |
|
| 112 |
+ NONSTOP* ) nonstop=true ;; |
|
| 113 |
+esac |
|
| 114 |
+ |
|
| 115 |
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar |
|
| 116 |
+ |
|
| 117 |
+ |
|
| 118 |
+# Determine the Java command to use to start the JVM. |
|
| 119 |
+if [ -n "$JAVA_HOME" ] ; then |
|
| 120 |
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then |
|
| 121 |
+ # IBM's JDK on AIX uses strange locations for the executables |
|
| 122 |
+ JAVACMD=$JAVA_HOME/jre/sh/java |
|
| 123 |
+ else |
|
| 124 |
+ JAVACMD=$JAVA_HOME/bin/java |
|
| 125 |
+ fi |
|
| 126 |
+ if [ ! -x "$JAVACMD" ] ; then |
|
| 127 |
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME |
|
| 128 |
+ |
|
| 129 |
+Please set the JAVA_HOME variable in your environment to match the |
|
| 130 |
+location of your Java installation." |
|
| 131 |
+ fi |
|
| 132 |
+else |
|
| 133 |
+ JAVACMD=java |
|
| 134 |
+ if ! command -v java >/dev/null 2>&1 |
|
| 135 |
+ then |
|
| 136 |
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
|
| 137 |
+ |
|
| 138 |
+Please set the JAVA_HOME variable in your environment to match the |
|
| 139 |
+location of your Java installation." |
|
| 140 |
+ fi |
|
| 141 |
+fi |
|
| 142 |
+ |
|
| 143 |
+# Increase the maximum file descriptors if we can. |
|
| 144 |
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then |
|
| 145 |
+ case $MAX_FD in #( |
|
| 146 |
+ max*) |
|
| 147 |
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. |
|
| 148 |
+ # shellcheck disable=SC2039,SC3045 |
|
| 149 |
+ MAX_FD=$( ulimit -H -n ) || |
|
| 150 |
+ warn "Could not query maximum file descriptor limit" |
|
| 151 |
+ esac |
|
| 152 |
+ case $MAX_FD in #( |
|
| 153 |
+ '' | soft) :;; #( |
|
| 154 |
+ *) |
|
| 155 |
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. |
|
| 156 |
+ # shellcheck disable=SC2039,SC3045 |
|
| 157 |
+ ulimit -n "$MAX_FD" || |
|
| 158 |
+ warn "Could not set maximum file descriptor limit to $MAX_FD" |
|
| 159 |
+ esac |
|
| 160 |
+fi |
|
| 161 |
+ |
|
| 162 |
+# Collect all arguments for the java command, stacking in reverse order: |
|
| 163 |
+# * args from the command line |
|
| 164 |
+# * the main class name |
|
| 165 |
+# * -classpath |
|
| 166 |
+# * -D...appname settings |
|
| 167 |
+# * --module-path (only if needed) |
|
| 168 |
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. |
|
| 169 |
+ |
|
| 170 |
+# For Cygwin or MSYS, switch paths to Windows format before running java |
|
| 171 |
+if "$cygwin" || "$msys" ; then |
|
| 172 |
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) |
|
| 173 |
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) |
|
| 174 |
+ |
|
| 175 |
+ JAVACMD=$( cygpath --unix "$JAVACMD" ) |
|
| 176 |
+ |
|
| 177 |
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh |
|
| 178 |
+ for arg do |
|
| 179 |
+ if |
|
| 180 |
+ case $arg in #( |
|
| 181 |
+ -*) false ;; # don't mess with options #( |
|
| 182 |
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
|
| 183 |
+ [ -e "$t" ] ;; #( |
|
| 184 |
+ *) false ;; |
|
| 185 |
+ esac |
|
| 186 |
+ then |
|
| 187 |
+ arg=$( cygpath --path --ignore --mixed "$arg" ) |
|
| 188 |
+ fi |
|
| 189 |
+ # Roll the args list around exactly as many times as the number of |
|
| 190 |
+ # args, so each arg winds up back in the position where it started, but |
|
| 191 |
+ # possibly modified. |
|
| 192 |
+ # |
|
| 193 |
+ # NB: a `for` loop captures its iteration list before it begins, so |
|
| 194 |
+ # changing the positional parameters here affects neither the number of |
|
| 195 |
+ # iterations, nor the values presented in `arg`. |
|
| 196 |
+ shift # remove old arg |
|
| 197 |
+ set -- "$@" "$arg" # push replacement arg |
|
| 198 |
+ done |
|
| 199 |
+fi |
|
| 200 |
+ |
|
| 201 |
+ |
|
| 202 |
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
|
| 203 |
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' |
|
| 204 |
+ |
|
| 205 |
+# Collect all arguments for the java command: |
|
| 206 |
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, |
|
| 207 |
+# and any embedded shellness will be escaped. |
|
| 208 |
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
|
| 209 |
+# treated as '${Hostname}' itself on the command line.
|
|
| 210 |
+ |
|
| 211 |
+set -- \ |
|
| 212 |
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \ |
|
| 213 |
+ -classpath "$CLASSPATH" \ |
|
| 214 |
+ org.gradle.wrapper.GradleWrapperMain \ |
|
| 215 |
+ "$@" |
|
| 216 |
+ |
|
| 217 |
+# Stop when "xargs" is not available. |
|
| 218 |
+if ! command -v xargs >/dev/null 2>&1 |
|
| 219 |
+then |
|
| 220 |
+ die "xargs is not available" |
|
| 221 |
+fi |
|
| 222 |
+ |
|
| 223 |
+# Use "xargs" to parse quoted args. |
|
| 224 |
+# |
|
| 225 |
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed. |
|
| 226 |
+# |
|
| 227 |
+# In Bash we could simply go: |
|
| 228 |
+# |
|
| 229 |
+# readarray ARGS < <( xargs -n1 <<<"$var" ) && |
|
| 230 |
+# set -- "${ARGS[@]}" "$@"
|
|
| 231 |
+# |
|
| 232 |
+# but POSIX shell has neither arrays nor command substitution, so instead we |
|
| 233 |
+# post-process each arg (as a line of input to sed) to backslash-escape any |
|
| 234 |
+# character that might be a shell metacharacter, then use eval to reverse |
|
| 235 |
+# that process (while maintaining the separation between arguments), and wrap |
|
| 236 |
+# the whole thing up as a single "set" statement. |
|
| 237 |
+# |
|
| 238 |
+# This will of course break if any of these variables contains a newline or |
|
| 239 |
+# an unmatched quote. |
|
| 240 |
+# |
|
| 241 |
+ |
|
| 242 |
+eval "set -- $( |
|
| 243 |
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | |
|
| 244 |
+ xargs -n1 | |
|
| 245 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | |
|
| 246 |
+ tr '\n' ' ' |
|
| 247 |
+ )" '"$@"' |
|
| 248 |
+ |
|
| 249 |
+exec "$JAVACMD" "$@" |
| 0 | 250 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,92 @@ |
| 1 |
+@rem |
|
| 2 |
+@rem Copyright 2015 the original author or authors. |
|
| 3 |
+@rem |
|
| 4 |
+@rem Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+@rem you may not use this file except in compliance with the License. |
|
| 6 |
+@rem You may obtain a copy of the License at |
|
| 7 |
+@rem |
|
| 8 |
+@rem https://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+@rem |
|
| 10 |
+@rem Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+@rem distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+@rem See the License for the specific language governing permissions and |
|
| 14 |
+@rem limitations under the License. |
|
| 15 |
+@rem |
|
| 16 |
+ |
|
| 17 |
+@if "%DEBUG%"=="" @echo off |
|
| 18 |
+@rem ########################################################################## |
|
| 19 |
+@rem |
|
| 20 |
+@rem Gradle startup script for Windows |
|
| 21 |
+@rem |
|
| 22 |
+@rem ########################################################################## |
|
| 23 |
+ |
|
| 24 |
+@rem Set local scope for the variables with windows NT shell |
|
| 25 |
+if "%OS%"=="Windows_NT" setlocal |
|
| 26 |
+ |
|
| 27 |
+set DIRNAME=%~dp0 |
|
| 28 |
+if "%DIRNAME%"=="" set DIRNAME=. |
|
| 29 |
+@rem This is normally unused |
|
| 30 |
+set APP_BASE_NAME=%~n0 |
|
| 31 |
+set APP_HOME=%DIRNAME% |
|
| 32 |
+ |
|
| 33 |
+@rem Resolve any "." and ".." in APP_HOME to make it shorter. |
|
| 34 |
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
|
| 35 |
+ |
|
| 36 |
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
|
| 37 |
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" |
|
| 38 |
+ |
|
| 39 |
+@rem Find java.exe |
|
| 40 |
+if defined JAVA_HOME goto findJavaFromJavaHome |
|
| 41 |
+ |
|
| 42 |
+set JAVA_EXE=java.exe |
|
| 43 |
+%JAVA_EXE% -version >NUL 2>&1 |
|
| 44 |
+if %ERRORLEVEL% equ 0 goto execute |
|
| 45 |
+ |
|
| 46 |
+echo. |
|
| 47 |
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
|
| 48 |
+echo. |
|
| 49 |
+echo Please set the JAVA_HOME variable in your environment to match the |
|
| 50 |
+echo location of your Java installation. |
|
| 51 |
+ |
|
| 52 |
+goto fail |
|
| 53 |
+ |
|
| 54 |
+:findJavaFromJavaHome |
|
| 55 |
+set JAVA_HOME=%JAVA_HOME:"=% |
|
| 56 |
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe |
|
| 57 |
+ |
|
| 58 |
+if exist "%JAVA_EXE%" goto execute |
|
| 59 |
+ |
|
| 60 |
+echo. |
|
| 61 |
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% |
|
| 62 |
+echo. |
|
| 63 |
+echo Please set the JAVA_HOME variable in your environment to match the |
|
| 64 |
+echo location of your Java installation. |
|
| 65 |
+ |
|
| 66 |
+goto fail |
|
| 67 |
+ |
|
| 68 |
+:execute |
|
| 69 |
+@rem Setup the command line |
|
| 70 |
+ |
|
| 71 |
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar |
|
| 72 |
+ |
|
| 73 |
+ |
|
| 74 |
+@rem Execute Gradle |
|
| 75 |
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* |
|
| 76 |
+ |
|
| 77 |
+:end |
|
| 78 |
+@rem End local scope for the variables with windows NT shell |
|
| 79 |
+if %ERRORLEVEL% equ 0 goto mainEnd |
|
| 80 |
+ |
|
| 81 |
+:fail |
|
| 82 |
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of |
|
| 83 |
+rem the _cmd.exe /c_ return code! |
|
| 84 |
+set EXIT_CODE=%ERRORLEVEL% |
|
| 85 |
+if %EXIT_CODE% equ 0 set EXIT_CODE=1 |
|
| 86 |
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% |
|
| 87 |
+exit /b %EXIT_CODE% |
|
| 88 |
+ |
|
| 89 |
+:mainEnd |
|
| 90 |
+if "%OS%"=="Windows_NT" endlocal |
|
| 91 |
+ |
|
| 92 |
+:omega |
| 0 | 93 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 1 |
+/* |
|
| 2 |
+ * Copyright (c) 2021 Samson Achiaga |
|
| 3 |
+ * |
|
| 4 |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
+ * you may not use this file except in compliance with the License. |
|
| 6 |
+ * You may obtain a copy of the License at |
|
| 7 |
+ * |
|
| 8 |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
+ * |
|
| 10 |
+ * Unless required by applicable law or agreed to in writing, software |
|
| 11 |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
+ * See the License for the specific language governing permissions and |
|
| 14 |
+ * limitations under the License. |
|
| 15 |
+ */ |
|
| 16 |
+ |
|
| 17 |
+rootProject.name = "Audio Note" |
|
| 18 |
+include ':app' |