Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ba294668fb |
@@ -30,7 +30,7 @@ ios/Index/DataStore
|
||||
build/
|
||||
.idea
|
||||
.gradle
|
||||
*.properties
|
||||
local.properties
|
||||
*.iml
|
||||
*.hprof
|
||||
|
||||
@@ -59,9 +59,8 @@ buck-out/
|
||||
# Bundle artifact
|
||||
*.jsbundle
|
||||
|
||||
# Ruby / CocoaPods
|
||||
# CocoaPods
|
||||
/ios/Pods/
|
||||
/vendor/bundle/
|
||||
|
||||
# RN android release
|
||||
android/app/bin/
|
||||
|
||||
@@ -8,7 +8,6 @@ cache:
|
||||
|
||||
test_async:
|
||||
script:
|
||||
- npm install npm@7.0.1 -g
|
||||
- npm install
|
||||
- npm test
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
## 🐛 Oh no, a bug 🐛
|
||||
|
||||
### What happened?
|
||||
|
||||
Short overview of how the bug manifests.
|
||||
|
||||
### What is the expected behaviour?
|
||||
|
||||
_It's supposed to show ... and not ..._
|
||||
|
||||
### Which OS + version is your device?
|
||||
|
||||
- [ ] Android _number_
|
||||
- [ ] iOS _number_
|
||||
- [ ] Simulator _number_
|
||||
|
||||
### Which drip version number are you using?
|
||||
|
||||
_On your phone, go to ➞ menu on the top right ➞ about, scroll to the very bottom, and find the version number_
|
||||
|
||||
### How did it happen?
|
||||
|
||||
_What triggered the bug/behavior, always/sometimes, is it reproducible(how)?_
|
||||
|
||||
### Describe how it looks or add a screenshot
|
||||
|
||||
Feel free to attach a file 📎
|
||||
|
||||
### Any ideas on how to solve it? 💡
|
||||
@@ -1,23 +0,0 @@
|
||||
## 🪠 This has to be done 🪠
|
||||
|
||||
### What has to be done?
|
||||
|
||||
Short overview
|
||||
|
||||
### Is it urgent? ⏳
|
||||
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
- [ ] Something in between
|
||||
|
||||
_Explain the urgency if possible, e.g. is it a security vulnerability for potentially everyone?_
|
||||
If it is a security vulnerability for potentially everyone, please reach out ASAP to drip@mailbox.org.
|
||||
|
||||
### Which OS?
|
||||
|
||||
- [ ] Android
|
||||
- [ ] iOS
|
||||
|
||||
### What should the ideal outcome be? 🎆
|
||||
|
||||
_You can, e.g., specify the version number for a library update_
|
||||
@@ -1,26 +0,0 @@
|
||||
## 🧩 Yeah, a feature idea! 🧩
|
||||
|
||||
### This feature is a ...
|
||||
|
||||
- [ ] period tracking feature (add more data points etc.)
|
||||
- [ ] technological feature (password, design, settings, etc.)
|
||||
|
||||
### What should this feature do or solve? 🪄
|
||||
|
||||
Please give a short overview so as many people as possible would be able to understand.
|
||||
|
||||
### Who is this feature for?
|
||||
|
||||
### What is particularly important to the people who would use this feature?
|
||||
|
||||
### Where in the app should the feature be added?
|
||||
|
||||
### Is it connected with or dependent on some other feature?
|
||||
|
||||
### How should the feature look (sketch or mock-up)?
|
||||
|
||||
Feel free to attach a file 📎
|
||||
|
||||
### What could be difficulties (esp. integrating with other components)? 🪆
|
||||
|
||||
### Do you want to work on this yourself?
|
||||
@@ -1,5 +1,7 @@
|
||||
## Why this change?
|
||||
|
||||
Closes ticket #
|
||||
|
||||
## Description
|
||||
|
||||
I have tested this MR:
|
||||
|
||||
@@ -2,173 +2,18 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## v1.2403.19 Android & iOS
|
||||
## v1.2102.28
|
||||
|
||||
### Changes
|
||||
|
||||
- Disables temperature slider if temperature tracking off
|
||||
- Disables secondary symptom if fertility and or cervix/cervical mucus are off
|
||||
- Disables temperature reminder if temperature tracking off
|
||||
- Disabled period reminder if period predictions off
|
||||
- Return from sympto adapter if fertility off
|
||||
- Restructure settings menu
|
||||
- Unify wording to "sympto-thermal method"
|
||||
- Format decimal to x.0 instead of x.00 used for standard deviation and average cycle in stats
|
||||
- Use SelectTabGroup for secondary symptom customization
|
||||
|
||||
- Android changes after updating React Native to 0.68.3
|
||||
- Update Android Gradle plugin from 7.0.3 to 7.0.4
|
||||
- Update NDK to "24.0.8215888" only for M1 users which added support for aarch64
|
||||
- Update metadata phone screenshots for Fdroid store listing
|
||||
- Updated dependencies:
|
||||
- @react-native-community/datetimepicker from 6.3.1 to 7.2.0
|
||||
- @react-native-async-storage/async-storage from ^1.17.9 to ^1.18.2
|
||||
- metro-react-native-babel-preset from ^0.66.2 to ^0.67.0
|
||||
|
||||
### Adds
|
||||
|
||||
- Customization settings can turn on & off:
|
||||
|
||||
- Tracking categories
|
||||
- Period predictions
|
||||
- Fertility phases calculation
|
||||
|
||||
- Home displays text elements depending on customization settings
|
||||
- Chart displays tracking category elements depending on customization settings
|
||||
- CycleDay displays tracking category elements and exclude switch depending on customization settings
|
||||
- Reminder can be disabled depending on customization settings
|
||||
- Adds disabled and more styling to AppSwitch
|
||||
- Adds TrackingCategorySwitch
|
||||
- Adds disabled, more styling and alert to SelectTabGroup
|
||||
- Adds more marginTop to License page
|
||||
- Adds info text to Password menu item in Settings
|
||||
|
||||
## v1.2401.17 iOS
|
||||
|
||||
### Changes
|
||||
|
||||
- Updating React Native to 0.68.3
|
||||
- Minor changes in temperature chart
|
||||
|
||||
### Adds
|
||||
|
||||
- Temperature scale slider
|
||||
- out of range warning messages for temperature values
|
||||
|
||||
### Fixed
|
||||
|
||||
- Order of import buttons
|
||||
|
||||
## v1.2312.11 iOS
|
||||
|
||||
### Changes
|
||||
|
||||
- Chart: Improved readability
|
||||
- Finer temperature lines and dots
|
||||
- Enlarge screen space for temperature chart
|
||||
- A very light grey background color for weekend days on the whole chart screen
|
||||
- Homescreen: date displayed in new format
|
||||
- Minor changes in "about" section
|
||||
|
||||
See more under v1.2311.14 Android
|
||||
|
||||
### Adds
|
||||
|
||||
- Stats: Show period details, including cycle start, cycle length and amount of days with bleeding
|
||||
- Stats: Explainer text for standard deviation
|
||||
- App asks for permissions for notifications right at the start, which allows you to set reminders (this is a new requirement for Android 13)
|
||||
|
||||
## v1.2311.14 Android
|
||||
|
||||
### Changes
|
||||
|
||||
- Make the app compatible with Android 13
|
||||
- Update Android's targetSdkVersion to 33
|
||||
- Update buildToolsVersion to 33.0.2
|
||||
- Update Android Gradle plugin to 7.0.3
|
||||
- Update Gradle to 7.3.3
|
||||
- Update kotlinVersion to 1.3.40
|
||||
- Chart: Improved readability
|
||||
- Finer temperature lines and dots
|
||||
- Enlarge screen space for temperature chart
|
||||
- A very light grey background color for weekend days on the whole chart screen
|
||||
- Reminders:
|
||||
- Use new fork of react-native-push-notification: <https://github.com/github:bl00dymarie/react-native-push-notification> without google services
|
||||
- Adding channels after breaking changes in react-native-push-notification
|
||||
- Homescreen: date displayed in new format
|
||||
- Minor changes in "about" section
|
||||
- Updated dependencies:
|
||||
- moment ^2.29.4,
|
||||
- prop-types ^15.8.1,
|
||||
- react v17.0.2,
|
||||
- react-native v0.67.4,
|
||||
- react-native-calendars ^1.1287.0,
|
||||
- react-native-document-picker ^8.1.1,
|
||||
- react-native-fs ^2.20.0,
|
||||
- react-native-modal-datetime-picker v14.0.0,
|
||||
- react-native-share ^7.9.0,
|
||||
- react-native-vector-icons ^9.2.0,
|
||||
- realm ^10.16.0,
|
||||
- sympto v3.0.1
|
||||
|
||||
### Adds
|
||||
|
||||
- Stats: Show period details, including cycle start, cycle length and amount of days with bleeding
|
||||
- Stats: Explainer text for standard deviation
|
||||
- Settings: Privacy Policy
|
||||
- App asks for permissions for notifications right at the start, which allows you to set reminders (this is a new requirement for Android 13)
|
||||
- Buttons can now be displayed as row
|
||||
|
||||
- Added dependencies:
|
||||
- @js-joda/core ^5.3.0,
|
||||
- @react-native-async-storage/async-storage ^1.17.9,
|
||||
- @react-native-community/art ^1.2.0,
|
||||
- @react-native-community/datetimepicker ^6.3.1,
|
||||
- @react-native-community/push-notification-ios ^1.11.0,
|
||||
- i18next ^22.0.2,
|
||||
- react-i18next ^12.0.0,
|
||||
- jshashes ^1.0.8,
|
||||
- react-native-permissions ^3.10.0,
|
||||
- react-native-push-notification: github:bl00dymarie/react-native-push-notification,
|
||||
- react-native-simple-toast ^1.1.3,
|
||||
- react-native-size-matters ^0.4.0,
|
||||
|
||||
### Fixed
|
||||
|
||||
- Password: Disable setting empty passwords
|
||||
- After updating the password the app will do a full restart
|
||||
- Chart: Grid for symptoms
|
||||
- Chart: Horizontal lines in temperature chart
|
||||
|
||||
### Unreleased
|
||||
|
||||
- Partially implemented translations with react-i18next
|
||||
|
||||
## v1.2208.11 iOS
|
||||
|
||||
### Adds
|
||||
|
||||
- first iOS Release
|
||||
|
||||
### Unreleased
|
||||
|
||||
- Temperature scale slider
|
||||
- Warning message for out of scope temperature values
|
||||
|
||||
## v1.2102.28 Android
|
||||
|
||||
### Changes
|
||||
|
||||
- Temperature range is now between 35 - 39°C and its default values are now set to 35.5 - 37.5°C
|
||||
|
||||
### Fixed
|
||||
|
||||
- Blocks invalid input of temperature value
|
||||
- Error message for incorrect password on login screen
|
||||
- Phase text on home screen for last fertile day
|
||||
- Styling improvements
|
||||
|
||||
## v1.2101.9 Android
|
||||
## v1.2101.9
|
||||
|
||||
### Adds
|
||||
|
||||
@@ -211,12 +56,12 @@ See more under v1.2311.14 Android
|
||||
- Fixed react-native-vector-icon
|
||||
- Fixed AppLoadingView component centering
|
||||
|
||||
## v0.2007-12.beta Android
|
||||
## v0.2007-12.beta
|
||||
|
||||
### Adds
|
||||
|
||||
- Allows chart not to show temperature part, when temperature is not tracked and corresponding refactoring
|
||||
- Detox support for e2e testing and addition of the e2e tests
|
||||
- Detox support for e2e testing and addition of the e2e tests
|
||||
- Introduces Redux global state (date and navigation are stored locally now)
|
||||
- Introduces clear.sh script to the project automising clearing project caches and packages reinstallation
|
||||
|
||||
@@ -235,7 +80,7 @@ See more under v1.2311.14 Android
|
||||
|
||||
- Fixed adding notes to the future dates
|
||||
- Fixed app exiting with error when hitting back button on device
|
||||
- Fixed Sex symptom showing on y axis of chart even though the contraception method was deleted
|
||||
- Fixed Sex symptom showing on y axis of chart even though the contraception method was deleted
|
||||
- Fixed of the clear.sh file name in package.json
|
||||
- Fixed of navigation from chart to the cycle day overview
|
||||
- Bug fix for maximum value of mucus not showing on chart
|
||||
@@ -246,7 +91,7 @@ See more under v1.2311.14 Android
|
||||
|
||||
- Updates of node.js to fix security issue
|
||||
|
||||
## v0.2005.3-beta Android
|
||||
## v0.2005.3-beta
|
||||
|
||||
- Adds arm64-v8a and x86_64 for supporting 64-bit architecture
|
||||
- Adds Mariya & Sofiya as contributors <3
|
||||
@@ -346,7 +191,7 @@ See more under v1.2311.14 Android
|
||||
- Adds release wizard
|
||||
- Updates nodejs-mobile to fix security issue
|
||||
|
||||
## v0.1905.29-beta Android
|
||||
## v0.1905.29-beta
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -367,7 +212,7 @@ See more under v1.2311.14 Android
|
||||
- Line width in chart
|
||||
- Prediction range in drop on homescreen
|
||||
|
||||
## v0.1905.28-beta Android
|
||||
## v0.1905.28-beta
|
||||
|
||||
- Displays all the text for Home Elements; Shortens margin btw Home Elements; Adds missing "visit" to text
|
||||
- Adds donation section to about
|
||||
@@ -442,7 +287,7 @@ See more under v1.2311.14 Android
|
||||
- Nicer formatting for past bleeding prediction
|
||||
- Fixed prediction range in drop on homescreen
|
||||
|
||||
## v0.1905.10-beta Android
|
||||
## v0.1905.10-beta
|
||||
|
||||
- Filter release commits from changelog
|
||||
- Adds update-changelog script
|
||||
@@ -467,7 +312,7 @@ See more under v1.2311.14 Android
|
||||
- Delete password button bug fix
|
||||
- temperature screen styling update
|
||||
|
||||
## v0.0.3 - 2019-04-17 Android
|
||||
## v0.0.3 - 2019-04-17
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -477,9 +322,9 @@ See more under v1.2311.14 Android
|
||||
|
||||
- Button functionality in settings for password
|
||||
|
||||
## v0.0.2 - 2019-04-09 Android
|
||||
## v0.0.2 - 2019-04-09
|
||||
|
||||
## Second updated beta release version Android
|
||||
## Second updated beta release version
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -493,9 +338,9 @@ See more under v1.2311.14 Android
|
||||
- Delete button for sex, pain and mood
|
||||
- Dates on chart
|
||||
|
||||
## v0.0.1 - 2019-02-15 Android
|
||||
## v0.0.1 - 2019-02-15
|
||||
|
||||
## First beta release version Android
|
||||
## First beta release version
|
||||
|
||||
### Added (list of core functionality)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Contributing to drip aka CONDRIPUTING
|
||||
So good to see you here, hello :wave\_tone1: :wave\_tone2: :wave\_tone3: :wave\_tone4: :wave\_tone5:
|
||||
|
||||
So good to see you here, hello :wave_tone1: :wave_tone2: :wave_tone3: :wave_tone4: :wave_tone5:
|
||||
|
||||
## Table Of Contents
|
||||
|
||||
[TL;DR](#tldr)
|
||||
[TL;DR](#tl-dr)
|
||||
|
||||
[What should I know before I get started?](#what-should-i-know-before-i-get-started)
|
||||
|
||||
@@ -14,44 +14,45 @@ So good to see you here, hello :wave_tone1: :wave_tone2: :wave_tone3: :wave_tone
|
||||
|
||||
## TL;DR
|
||||
|
||||
You just want to say hello? Send us a [nice email](mailto:drip@mailbox.org?Subject=Nice%20incoming%20mail) :postbox:, toot :mammoth: [@dripapp@mastodon.social](https://mastodon.social/@dripapp) or tweet :bird: at us [@dripberlin](https://twitter.com/dripberlin).
|
||||
You just want to say hello? Send us a [nice email](mailto:drip@mailbox.org?Subject=Nice%20incoming%20mail) :postbox:, ask to [join our Slack](mailto:drip@mailbox.org?Subject=Join%20Slack) or tweet :bird: at us [@dripberlin](https://twitter.com/dripberlin).
|
||||
|
||||
## What should I know before I get started?
|
||||
|
||||
We have prepared something for **you**: check out our [README](https://gitlab.com/bloodyhealth/drip/blob/main/README.md) for more information on how to set up and install everything you'll need.
|
||||
[Ping us](mailto:drip@mailbox.org) if you could need some help :helmet_with_cross: !
|
||||
We have prepared something for **you**: check out our [README](https://gitlab.com/bloodyhealth/drip/blob/master/README.md) for more information on how to set up and install everything you'll need.
|
||||
[Ping us](mailto:drip@mailbox.org) if you could need some help :helmet\_with\_cross: !
|
||||
|
||||
Let us know if you want to suggest improvements for the README and open a merge request (which is just like Github's pull request)
|
||||
|
||||
## How can I condripute?
|
||||
|
||||
We are an open source project and we highly appreciate contributions. At the same time please keep some things in mind: :heart:
|
||||
### Your First Code Condripution
|
||||
|
||||
- The drip maintainers are usually around 2-3 people and are responsible for everything from developing new features to answering press inquiries or fixing bugs. Most of this work is done unpaid. (If you write a nice email your chances to get an answer are much higher than if you behave like a tech bro.)
|
||||
- We have a plan for the direction in which drip should evolve. This means that even if it isn't always transparent on gitlab, we have a list of features that we are building and more importantly, which bugs need to be fixed and which dependencies need to be updated.
|
||||
- drips core values are:
|
||||
- 🔮 open source
|
||||
- 🩸 feminist and gender inclusive
|
||||
- 🔒 secure: data entered stays with that person/on their device
|
||||
- 🔬 science-based: we implemented the sympto-thermal method
|
||||
We are fans of labels, at least for our issues. You can find a list of `newbie` issues [here](https://gitlab.com/bloodyhealth/drip/issues?label_name%5B%5D=Newbie).
|
||||
If you decide to work on an issue, please click on `Create branch` based on that issue. You can find this as a dropdown option right under `Create merge request`.
|
||||
This allows us to keep track of the issues that are related to an existing branch and tells everyone "somebody is working on it".
|
||||
|
||||
This means that we will never implement anything that contradicts these core values. Some examples: We will never build a cloud integration, we will never make an ovulation prediction.
|
||||
If you want to open a merge request, yeah :tada: exciting! We are using a template for merge requests to make sure we explain what we have done and why.
|
||||
Keep in mind that people who will review your merge request are more motivated to do so when the merge request is well explained and ideally not too big.
|
||||
|
||||
- If you would like to make a sustainable contribution to the project, we would be happy to join the game.
|
||||
### Reporting Bugs
|
||||
|
||||
### Reporting Bugs or Making Suggestions
|
||||
You found a bug :bug:? Please feel free to investigate and save logs for more specific details.
|
||||
|
||||
If you found a bug or have suggestions, please :one: first review the [list of existing issues](https://gitlab.com/bloodyhealth/drip/issues) to make sure the bug/suggestion is unknown; :two: after that, take time to investigate and write a detailed issue report. Best you use our [templates for bug /chore/ feature](https://gitlab.com/bloodyhealth/drip/-/tree/main/.gitlab/issue_templates) (you can choose when creating a new issue) in gitlab or send us an email to our [gitlab email](mailto:incoming+bloodyhealth/drip@incoming.gitlab.com). It will automagically add a new issue to the list with a description text taken from the body of your email. Please attach screenshots or other helpful things.
|
||||
Before creating a new issue, please review the [list of existing issues](https://gitlab.com/bloodyhealth/drip/issues) to make sure the bug is unknown. You are invited to describe the bug in all its details e.g. in what context/settings has it occurred?
|
||||
|
||||
### Your First Condripution
|
||||
To send us a new issue you can also use our [gitlab email](mailto:incoming+bloodyhealth/drip@incoming.gitlab.com). It will automagically add a new issue to the list with a description text taken from the body of your email.
|
||||
|
||||
- If you want to contribute to drip's code or translation, please get in touch with us. We can tell you if someone is already working on something similar, if your idea does (not) match drip's core values, etc. Of course, you can always create a drip version for your private use with anything you want, but please don't expect us to review and merge code that has not been discussed before.
|
||||
- If you want to open a merge request, yeah :tada: exciting! We are using a template for merge requests to make sure we explain what we have done and why.
|
||||
- Keep in mind that people who will review your merge request are more motivated to do so when the merge request is well explained and ideally not too big.
|
||||
### Suggesting Enhancements
|
||||
|
||||
Do you have suggestions for enhancing the app or for cleaning up some code? Fantastic!
|
||||
|
||||
Before creating a new issue, please review the [list of existing issues](https://gitlab.com/bloodyhealth/drip/issues) to make sure nobody else had the same idea before you! You are then invited to open a new issue with a somewhat extensive description, you can use emojis or GIFs if it helps :)!
|
||||
|
||||
To send us a new issue you can also use our [gitlab email](mailto:incoming+bloodyhealth/drip@incoming.gitlab.com). It will automagically add a new issue to the list with the title taken from the subject line and the description text for the issue taken from the body of your email.
|
||||
|
||||
### Thank you
|
||||
|
||||

|
||||
|
||||
Thank you for condriputing to open source, thank you for condriputing to drip!
|
||||
Much love from Bloody Health :heart_exclamation:
|
||||
Much love from Bloody Health :heart\_exclamation:
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.5)
|
||||
rexml
|
||||
activesupport (6.1.5)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.11.3)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.11.3)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.4.0, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 1.0, < 3.0)
|
||||
xcodeproj (>= 1.21.0, < 2.0)
|
||||
cocoapods-core (1.11.3)
|
||||
activesupport (>= 5.0, < 7)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
netrc (~> 0.11)
|
||||
public_suffix (~> 4.0)
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.5)
|
||||
cocoapods-downloader (1.5.1)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.1)
|
||||
cocoapods-trunk (1.6.0)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.1.9)
|
||||
escape (0.0.4)
|
||||
ethon (0.15.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.15.5)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.10.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.6.1)
|
||||
minitest (5.15.0)
|
||||
molinillo (0.8.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
public_suffix (4.0.6)
|
||||
rexml (3.2.5)
|
||||
ruby-macho (2.5.1)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.21.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
zeitwerk (2.5.4)
|
||||
PLATFORMS
|
||||
ruby
|
||||
DEPENDENCIES
|
||||
cocoapods (~> 1.11, >= 1.11.2)
|
||||
RUBY VERSION
|
||||
ruby 2.7.4p191
|
||||
BUNDLED WITH
|
||||
2.2.27
|
||||
@@ -3,24 +3,21 @@
|
||||
A menstrual cycle tracking app that's open-source and leaves your data on your phone. Use it to track your menstrual cycle and/or for fertility awareness!
|
||||
Find more information on [our website](https://dripapp.org/).
|
||||
|
||||
[<img src="https://dripapp.org/assets/get.png"
|
||||
[<img src="https://dripapp.org/assets/get.png"
|
||||
alt="Get it here"
|
||||
height="55">](https://dripapp.org/release/v1.2311.14.apk)
|
||||
[<img src="https://dripapp.org/assets/badge_google-play.png"
|
||||
alt="Get it on Google Play"
|
||||
height="55">](https://dripapp.org/android)
|
||||
[<img src="https://dripapp.org/assets/badge_app-store.png"
|
||||
alt="Get drip on the App Store"
|
||||
height="55">](https://dripapp.org/ios)
|
||||
[<img src="https://dripapp.org/assets/badge_f-droid.png"
|
||||
height="55">](https://dripapp.org/release/8.apk)
|
||||
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||
alt="Get it on F-Droid"
|
||||
height="55">](https://dripapp.org/fdroid)
|
||||
height="80">](https://f-droid.org/packages/com.drip/)
|
||||
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png"
|
||||
alt="Get it on Google Play"
|
||||
height="80">](https://play.google.com/store/apps/details?id=com.drip)
|
||||
|
||||
The app is built in React Native and developed for Android and iOS.
|
||||
The app is built in React Native and currently developed for Android.
|
||||
|
||||
▶ [How to contribute to the project](https://gitlab.com/bloodyhealth/drip/blob/main/CONTRIBUTING.md)
|
||||
▶ [How to contribute to the project](https://gitlab.com/bloodyhealth/drip/blob/master/CONTRIBUTING.md)
|
||||
|
||||
▶ [How to release a new version](https://gitlab.com/bloodyhealth/drip/blob/main/RELEASE.md)
|
||||
▶ [How to release a new version](https://gitlab.com/bloodyhealth/drip/blob/master/RELEASE.md)
|
||||
|
||||
## Development setup
|
||||
|
||||
@@ -34,34 +31,16 @@ or clone it with HTTPS
|
||||
|
||||
git clone https://gitlab.com/bloodyhealth/drip.git
|
||||
|
||||
### 2. Node version
|
||||
### 2. Node & yarn version
|
||||
|
||||
Make sure you are running Node 14 and classic yarn (v.1). It's easiest to switch Node versions using `nvm`, here's how to install NVM: https://github.com/nvm-sh/nvm#installing-and-updating. After installing nvm close the terminal and open it again to be able to use nvm.
|
||||
Once you have nvm running you can install node 14:
|
||||
Make sure you are running Node 14 and classic yarn (v.1). It's easiest to switch Node versions using `nvm`, here's how to install NVM: https://github.com/nvm-sh/nvm#installing-and-updating. Once you have nvm you can install node 14:
|
||||
|
||||
nvm install v14.19.3
|
||||
|
||||
#### On Apple Silicon M1
|
||||
and then run
|
||||
|
||||
NodeJS 14 does not compile on the M1 architecture, so it has to be installed through Rosetta: https://devzilla.io/using-nodejs-14-with-mac-silicon-m1 .
|
||||
To activate Rosetta and switch to intel emulation run:
|
||||
|
||||
arch -x86_64 zsh
|
||||
|
||||
Run
|
||||
|
||||
arch
|
||||
|
||||
again to verify that it returns "i386".
|
||||
Now install node 14:
|
||||
|
||||
nvm install v14.19.3
|
||||
|
||||
### 3. Yarn version
|
||||
|
||||
use npm to install yarn:
|
||||
|
||||
npm install --global yarn
|
||||
cd drip
|
||||
yarn install
|
||||
|
||||
## for Android
|
||||
|
||||
@@ -71,46 +50,21 @@ Install [Android Studio](https://developer.android.com/studio/) - you'll need it
|
||||
|
||||
### 3.2 More requirements from Android Studio
|
||||
|
||||
Open Android Studio. If the message "SDK location not found" appears when you try to start it, edit `.bashrc` in your home directory by adding:
|
||||
|
||||
export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
|
||||
|
||||
Check by typing in your terminal:
|
||||
|
||||
echo $ANDROID_SDK_ROOT
|
||||
|
||||
You should see the path of Sdk.
|
||||
If you haven't installed [adb tools](https://developer.android.com/tools/adb) before, you will also have to do so and add to the .bashrc
|
||||
|
||||
PATH="$PATH:$HOME/Android/Sdk/platform-tools"
|
||||
|
||||
In Android Studio click on "Open an existing Android Studio project". Navigate to the drip repository you cloned and double click the android folder. It detects, downloads and cofigures requirements that might be missing, like the NDK and CMake to build the native code part of the project.
|
||||
Open Android Studio and click on "Open an existing Android Studio project". Navigate to the drip repository you cloned and double click the android folder. It detects, downloads and cofigures requirements that might be missing, like the NDK and CMake to build the native code part of the project.
|
||||
|
||||
### 3.3 Run the app on Android
|
||||
|
||||
Either create and start a [virtual device in Android Studio](https://developer.android.com/studio/run/emulator) or [set your physical device like your Android phone up](https://developer.android.com/training/basics/firstapp/running-app) to run the app.
|
||||
Either start a [virtual device in Android Studio](https://developer.android.com/studio/run/emulator) or [set your physical device like your Android phone up](https://developer.android.com/training/basics/firstapp/running-app) to run the app.
|
||||
|
||||
i. Open a terminal, navigate to the drip folder and run
|
||||
i. Open a terminal and run
|
||||
|
||||
yarn install
|
||||
|
||||
In a separate tab, that needs to keep running as long as you want to keep the app connected, run
|
||||
|
||||
yarn start
|
||||
|
||||
Also run in a new tab
|
||||
|
||||
yarn android
|
||||
|
||||
ii. To see logging output, run the following command in another tab:
|
||||
|
||||
yarn log
|
||||
|
||||
iii. If you had an older version of drip before and you are now trying to run a new drip version, clear cache by running
|
||||
|
||||
yarn clear
|
||||
|
||||
iv. Run the following command and select enable hot reloading (see https://facebook.github.io/react-native/docs/debugging.html):
|
||||
iii. Run the following command and select enable hot reloading (see https://facebook.github.io/react-native/docs/debugging.html):
|
||||
|
||||
adb shell input keyevent 82
|
||||
|
||||
@@ -131,36 +85,20 @@ Minimum system requirements to run iOS app are as follows:
|
||||
- MacOS 10.15.7 for Mac users
|
||||
- Xcode 13 (command line tools only might be enough)
|
||||
|
||||
i. Install yarn dependencies
|
||||
|
||||
yarn install ..
|
||||
|
||||
ii. Install XCode dependencies by running the following command from the root project directory:
|
||||
i. Install XCode dependencies by running the following command from the root project directory:
|
||||
|
||||
cd ios && pod install && cd ..
|
||||
|
||||
iii. To run app either open drip workspace ('drip.xcworkspace' file) with XCode and run "Build" or run the following command:
|
||||
ii. To run app either open drip workspace ('drip.xcworkspace' file) with XCode and run "Build" or run the following command:
|
||||
|
||||
yarn ios
|
||||
|
||||
iiii. If you are building the app with XCode make sure you are running this as well:
|
||||
iii. If you are building the app with XCode make sure you are running this as well:
|
||||
|
||||
yarn start
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### [MacOS M1] Flipper problems
|
||||
|
||||
If a bug in the currently used Flipper version prevents building the project, comment out the respective line in the podfile, like so:
|
||||
|
||||
#use_flipper!()
|
||||
|
||||
Run
|
||||
|
||||
pod install
|
||||
|
||||
from the ios directory again to reload the dependencies.
|
||||
|
||||
#### [MacOS] Java problems
|
||||
|
||||
Make sure that you have Java 1.8 by running `java -version`.
|
||||
@@ -209,7 +147,7 @@ You can run the tests with:
|
||||
|
||||
### End to end tests
|
||||
|
||||
1. Check what testing device is specified in [package.json](https://gitlab.com/bloodyhealth/drip/blob/main/package.json) under:
|
||||
1. Check what testing device is specified in [package.json](https://gitlab.com/bloodyhealth/drip/blob/master/package.json) under:
|
||||
```
|
||||
{"detox":
|
||||
{"configurations":
|
||||
|
||||
@@ -1,208 +1,33 @@
|
||||
# How to release
|
||||
# How to release a new version
|
||||
|
||||
drip is developed in React Native for iOS and Android and is released on 4 different platforms:
|
||||
Note: You need the release-key to bundle a release that can be uploaded to Google Play Store.
|
||||
|
||||
1. [Google Play Store](https://play.google.com/store/apps/details?id=com.drip)
|
||||
2. [Apple App Store](https://apps.apple.com/us/app/drip/id1584564949)
|
||||
3. [F-Droid](https://f-droid.org/packages/com.drip/)
|
||||
4. [drip Website](https://dripapp.org)
|
||||
|
||||
In an ideal world the app version is the same across platforms. In the past this has never been the case. The release v1.2403.19 is the first to be up to date on all 4 platforms!
|
||||
|
||||
Releasing a new version is very exciting and brings happy changes like fixing a bug, improving a feature, updating dependencies or adding a new functionality to the app. It is more than just pressing the button "publish new version".
|
||||
|
||||
_Note_: You need the release-key for Android to bundle a signed release that can be uploaded and published via the Google Play Store. A similar process for Apple requires a certificate to upload and publish the app to the App Store.
|
||||
|
||||
## Release steps
|
||||
|
||||
### 1. [Code](#code)
|
||||
- 1.1 [Version updating](#version-updating)
|
||||
- 1.2 [Android builds](#android-builds)
|
||||
- 1.3 [iOS builds](#ios-builds)
|
||||
- 1.4 [User testing](#user-testing)
|
||||
- 1.5 [Release tag](#release-tag)
|
||||
|
||||
### 2. [Documentation](#documentation)
|
||||
- 2.1 [Changelog](#changelog)
|
||||
- 2.2 [Release notes](#release-notes)
|
||||
- 2.3 [Releases on Gitlab](#releases-on-gitlab)
|
||||
- 2.4 [Phone screenshots](#phone-screenshots)
|
||||
|
||||
### 3. [Publishing](#publishing)
|
||||
- 3.1 [Google Play Console](#google-play-console)
|
||||
- 3.2 [Apple App Store Connect](#apple-app-store-connect)
|
||||
- 3.3 [F-droid](#f-droid)
|
||||
- 3.4 [drip website](#drip-website)
|
||||
- 3.5 [Communication](#communication)
|
||||
- 3.6 [Self care](#self-care)
|
||||
|
||||
## Code
|
||||
|
||||
### Version updating
|
||||
|
||||
When you are done with a chore, a feature or a bugfix, you may want to share it with testers and eventually publish a release. In order to identify a specific app version we can update the version name, which is created based on the following format: `1.yymm.d` e.g. `1.2311.7`. If you want to upload a new app version to Google Play you also need to update the version code.
|
||||
|
||||
The following command will:
|
||||
|
||||
- create a new versionName and a new higher versionCode (+1)
|
||||
- create a commit including a tag named after the new release version name.
|
||||
Run the release wizard that takes you through all the steps necessary to prepare a new release:
|
||||
|
||||
```
|
||||
yarn release
|
||||
npm run release
|
||||
```
|
||||
This will trigger the following:
|
||||
* update version number
|
||||
* create a new tag for the release
|
||||
* update the changelog
|
||||
* make a release commit
|
||||
|
||||
The versionName and versionCode [are defined here](https://gitlab.com/bloodyhealth/drip/-/blob/5401789c46f4a02915ab900ef284581be420451c/android/app/build.gradle#L137-138) and in [package.json](https://gitlab.com/bloodyhealth/drip/-/blob/5401789c46f4a02915ab900ef284581be420451c/package.json#L3).
|
||||
|
||||
**Note for iOS**
|
||||
|
||||
Update the version number for iOS in `ios/drip/Info.plist` under:
|
||||
To then bundle a release run the following command on your branch:
|
||||
|
||||
```
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.2403.19</string>
|
||||
cd android && ./gradlew bundleRelease
|
||||
```
|
||||
|
||||
### Android builds
|
||||
This command creates an `app.aab` file in the folder `/android/app/build/outputs/bundle/release`.
|
||||
|
||||
APK versus AAB
|
||||
[More on Android App Bundle](https://blog.swmansion.com/make-your-react-native-app-3x-smaller-44c993eda2c9)
|
||||
|
||||
> Android App Bundles (AAB) include all your app’s compiled code and resources, but defer APK generation and signing to Google Play. Unlike an APK, you can't deploy an app bundle directly to a device. So, if you want to quickly test or share an APK with someone else, you should instead build an APK.
|
||||
|
||||
(https://developer.android.com/build/building-cmdline)
|
||||
|
||||
#### APK
|
||||
|
||||
To build a release apk file, run the following command:
|
||||
You need to manually push the created tag to Gitlab:
|
||||
|
||||
```
|
||||
yarn build-android-apk-release
|
||||
git push origin <tagname>
|
||||
```
|
||||
Also don't forget to push your branch to Gitlab and review and merge it if ready!
|
||||
|
||||
_which is a shortcut for:_ `cd android && ./gradlew clean && ./gradlew assembleRelease && cd ..`
|
||||
|
||||
This will create a new apk file named `app-release.apk` under `./android/app/build/outputs/apk/release/`.
|
||||
|
||||
For signing an apk you can run this command:
|
||||
|
||||
```
|
||||
yarn sign-android-apk-release
|
||||
```
|
||||
|
||||
_which is a shortcut for:_ `zipalign -v -p 4 ./android/app/build/outputs/apk/release/app-release.apk ./android/app/build/outputs/apk/release/app-release_signed.apk`
|
||||
|
||||
It adds a file name `app-release_signed.apk` in the same folder in `./android/app/build/outputs/apk/release/`
|
||||
|
||||
#### AAB
|
||||
|
||||
To build a release aab file, run:
|
||||
|
||||
```
|
||||
yarn build-android-aab-release
|
||||
```
|
||||
|
||||
_which is a shortcut for:_ `cd android && ./gradlew clean && ./gradlew :app:bundleRelease && cd ..`
|
||||
|
||||
It creates a new aab file named `app-release.aab` under `./android/app/build/outputs/bundle/release`
|
||||
|
||||
For signing an aab you first need to configure the base module’s build.gradle file with your app’s signing information. You can then run this command:
|
||||
|
||||
```
|
||||
yarn sign-android-aab-release
|
||||
```
|
||||
|
||||
_which is a shortcut for:_ `jarsigner -keystore ./android/app/drip-release-key.keystore ./android/app/build/outputs/bundle/release/app-release.aab drip-release-key`
|
||||
|
||||
### iOS builds
|
||||
|
||||
To build an .ipa archive file for an upload to the AppStore you need to go to xCode and select Build -> "Any iOS Device" and under "Product" -> "Archive".
|
||||
|
||||
Once the archiving process has completed you can chose to do the following:
|
||||
|
||||
"Distribute the app"
|
||||
|
||||
- TestFlight & App Store for when you want to upload it for external testing and/or production release
|
||||
- TestFlight Internal Only for when you want to upload it for internal testing
|
||||
|
||||
### User testing
|
||||
|
||||
To enable external testing you need to remember that Google Play and Apple App Store might take up to 1 day for their review process. "External testing" for iOS allows testing drip on Testflight anonymously via a public link. "Open testing" for Android allows testing drip on Google Play as beta tester below the normal production listing.
|
||||
|
||||
For a quick and easy way to share an apk to testers who are willing to sideload drip onto their Android phones, do this: Upload a signed apk to the Gitlab repository of the drip website under `/release` https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/tree/main/release and maybe adapt the name of the apk with a more specific name than "app-release.apk". Now you can simply share a direct link to download your newly bundled apk, e.g. [a download link for v1.2311.14](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/blob/main/release/v1.2311.14.apk).
|
||||
|
||||
### Release tag
|
||||
|
||||
[Tags](https://gitlab.com/bloodyhealth/drip/-/tags) can mark a specific point in the coding/commmit history and helps us identify the version status of a released app. They are named "iOS-v1.2401.17" or "Release-v1.yymm.d".
|
||||
|
||||
Any tag starting with "Release" or "Android" will be checked by https://gitlab.com/fdroidci
|
||||
|
||||
## Documentation
|
||||
|
||||
### Changelog
|
||||
|
||||
The [changelog](https://gitlab.com/bloodyhealth/drip/-/blob/main/CHANGELOG.md) should reflect the technical / code changes between a previous and the new version. Please update the changelog file with any relevant additions, fixes and changes in the following format:
|
||||
|
||||
>**v1.yymm.d**
|
||||
>
|
||||
>**Changes**
|
||||
>
|
||||
>Changing the color of funky button
|
||||
>Updating a library from 1.2.3 to 2.3.4
|
||||
>
|
||||
>**Adds**
|
||||
>
|
||||
>New feature for calendar
|
||||
>
|
||||
>**Fixed**
|
||||
>
|
||||
>Small bug in chart
|
||||
|
||||
### Release notes
|
||||
|
||||
These notes are for the users and curious ones who may want to start using drip. They should be based on the changelog but written in a friendly and easy to understand way. The focus is on the user perspective and the impact of the changes for the user. Behind the scenes and in depth code changes are less relevant.
|
||||
|
||||
Google Play limits these notes to 500 characters, whereas Apple's App Store limits these notes to 4.000 characters. In Fdroid there are no release notes.
|
||||
|
||||
### Releases on Gitlab
|
||||
|
||||
Under [Releases](https://gitlab.com/bloodyhealth/drip/-/releases) we keep track of all drip releases.
|
||||
|
||||
### Phone screenshots
|
||||
|
||||
If there are visual changes in the app you may want to update the screenshots for the Google Play Store listing, which allows up to 8 and for Apple's App Store, which allows up to 10 screenshots. Keep in mind that both Google Play and Apple have specific resolution requirements. You'll find Google's in Grow -> Store presence -> Main Store Listing -> Phone screenshots and Apple's on the main App Store Connect site. Here is a link for [Apple's screenshot specifications](https://developer.apple.com/help/app-store-connect/reference/screenshot-specifications).
|
||||
|
||||
Please also update [phone screenshots for the website](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/tree/main/assets) and set links on [/index](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/blob/f3da9776b1943ffa32458e74ef86eeca98c1891c/index.html#L47) and [/media](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/blob/c7f999bb7ad736345321537cbffa3f4c24eeee6d/media.html#L33) that can then also be attached to a social media post.
|
||||
|
||||
## Publishing
|
||||
|
||||
### Google Play Console
|
||||
|
||||
Upload a signed aab to the [Google Play Console for developers](https://play.google.com/console/) and add it to the "App bundle explorer". This requires a higher versionCode and a different version name compared to previously uploaded aab or apk files.
|
||||
You can decide if you want the new app version to get released for testing (internal, closed or open) or for production. Keep in mind that any track other than "internal testing" triggers an external review by Google and might take a few hours.
|
||||
|
||||
### Apple App Store Connect
|
||||
|
||||
Upload a new version and submit it for review, before it can be published.
|
||||
|
||||
### F-droid
|
||||
|
||||
This account runs automated checks for drip looking at new `Release` or `Android` [tags](https://gitlab.com/bloodyhealth/drip/-/tags/) and updates the app's metadata yaml file in Fdroid without further ado.
|
||||
|
||||
However this is not the full story. Please have a look at previous commits to see what necessary changes got pushed, [see here](https://gitlab.com/fdroid/fdroiddata/-/commits/master/metadata/com.drip.yml).
|
||||
|
||||
### drip website
|
||||
|
||||
After a new version has been published on Google Play (or F-Droid) the apk version that is downloadable directly from the [drip website](https://dripapp.org) needs to get updated as well. Therefore you upload a signed apk to the [repository](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/) as [we did in this commit](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/commit/f8c0f90c1ae9f23bf8e1bc311790b85443149a4d), and adapt the name and link on /index.html [as we did in this commit](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/commit2f8850ff5fa78615a4f335b625ea4a67d4acf03a) and [this commit](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/commit/f3da9776b1943ffa32458e74ef86eeca98c1891c). Last time I checked it was [here](f3da9776b1943ffa32458e74ef86eeca98c1891c/index.html#L114).
|
||||
|
||||
### Communication
|
||||
|
||||
You probably want to share the app update by posting on one or more of these platforms:
|
||||
|
||||
- [Twitter](twitter.com/dripberlin)
|
||||
- [Mastodon](mastodon.social/@dripapp)
|
||||
- [Ko-fi](https://ko-fi.com/dripapp)
|
||||
- [Linkedin](https://www.linkedin.com/company/34899684/)
|
||||
- Different tech, privacy, feminist oriented slacks
|
||||
|
||||
### Self care
|
||||
|
||||
Congratulations. Take a break, eat some chocolate, go see a live show of your favorite band, masturbate <3!
|
||||
Yay, done (have a scoop of ice cream, I suggest coconut 🍦)!
|
||||
@@ -1,8 +1,6 @@
|
||||
apply plugin: "com.android.application"
|
||||
|
||||
import com.android.build.OutputFile
|
||||
import java.util.Properties
|
||||
import java.io.FileInputStream
|
||||
|
||||
/**
|
||||
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||
@@ -127,16 +125,6 @@ def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
*/
|
||||
def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
|
||||
|
||||
// Create a variable called keystorePropertiesFile, and initialize it to your
|
||||
// keystore.properties file, in the rootProject folder.
|
||||
def keystorePropertiesFile = rootProject.file("keystore.properties")
|
||||
|
||||
// Initialize a new Properties() object called keystoreProperties.
|
||||
def keystoreProperties = new Properties()
|
||||
|
||||
// Load your keystore.properties file into the keystoreProperties object.
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
|
||||
android {
|
||||
ndkVersion rootProject.ext.ndkVersion
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
@@ -146,10 +134,10 @@ android {
|
||||
applicationId "com.drip"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 38
|
||||
versionName "1.2410.22"
|
||||
versionCode 8
|
||||
versionName "1.2102.28"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a"
|
||||
}
|
||||
testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
@@ -162,10 +150,6 @@ android {
|
||||
keyPassword 'android'
|
||||
}
|
||||
release {
|
||||
storeFile file('drip-release-key.keystore')
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storePassword keystoreProperties['storePassword']
|
||||
if (project.hasProperty('DRIP_RELEASE_STORE_FILE')) {
|
||||
storeFile file(DRIP_RELEASE_STORE_FILE)
|
||||
storePassword DRIP_RELEASE_STORE_PASSWORD
|
||||
@@ -214,7 +198,7 @@ android {
|
||||
// For each separate APK per architecture, set a unique version code as described here:
|
||||
// https://developer.android.com/studio/build/configure-apk-splits.html
|
||||
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
|
||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2]
|
||||
def abi = output.getFilter(OutputFile.ABI)
|
||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||
output.versionCodeOverride =
|
||||
@@ -227,12 +211,11 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation "androidx.appcompat:appcompat:1.0.0"
|
||||
implementation "androidx.annotation:annotation:1.1.0"
|
||||
implementation "androidx.work:work-runtime-ktx:2.7.1"
|
||||
implementation 'androidx.appcompat:appcompat:1.0.0'
|
||||
implementation 'androidx.annotation:annotation:1.1.0'
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="28"
|
||||
tools:ignore="GoogleAppIndexingWarning">
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*/
|
||||
package com.drip;
|
||||
package com.rndiffapp;
|
||||
import android.content.Context;
|
||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
||||
import com.facebook.flipper.android.utils.FlipperUtils;
|
||||
@@ -18,7 +18,6 @@ import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
|
||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
||||
import com.facebook.react.ReactInstanceEventListener;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
@@ -47,7 +46,7 @@ public class ReactNativeFlipper {
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext == null) {
|
||||
reactInstanceManager.addReactInstanceEventListener(
|
||||
new ReactInstanceEventListener() {
|
||||
new ReactInstanceManager.ReactInstanceEventListener() {
|
||||
@Override
|
||||
public void onReactContextInitialized(ReactContext reactContext) {
|
||||
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||
|
||||
@@ -5,81 +5,74 @@
|
||||
>
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission tools:node="remove" android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission tools:node="remove" android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission tools:node="remove" android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
<permission
|
||||
android:name="${applicationId}.permission.C2D_MESSAGE"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:name=".MainApplication"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<meta-data
|
||||
android:name="com.dieam.reactnativepushnotification.notification_foreground"
|
||||
android:value="false" />
|
||||
<meta-data
|
||||
android:name="com.dieam.reactnativepushnotification.notification_color"
|
||||
android:resource="@color/purple" />
|
||||
<meta-data
|
||||
android:name="com.dieam.reactnativepushnotification.default_notification_channel_id"
|
||||
android:value="..." />
|
||||
|
||||
<receiver
|
||||
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions"
|
||||
android:exported="false"
|
||||
tools:ignore="MissingClass" />
|
||||
<receiver
|
||||
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher"
|
||||
android:exported="false" />
|
||||
<receiver
|
||||
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver"
|
||||
android:exported="false" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustPan"
|
||||
android:screenOrientation="sensorPortrait"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustPan"
|
||||
android:screenOrientation="sensorPortrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="com.drip.provider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false" >
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
tools:replace="android:resource"
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
</provider>
|
||||
|
||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
|
||||
android:value="false"/>
|
||||
<!-- Change the resource name to your App's accent color - or any other color you want -->
|
||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
|
||||
android:resource="@android:color/white"/> <!-- or @android:color/{name} to use a standard color -->
|
||||
|
||||
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
|
||||
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
|
||||
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
|
||||
android:exported="false" >
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.drip;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.ReactRootView;
|
||||
|
||||
public class MainActivity extends ReactActivity {
|
||||
|
||||
@@ -14,27 +12,4 @@ public class MainActivity extends ReactActivity {
|
||||
protected String getMainComponentName() {
|
||||
return "drip";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
|
||||
* you can specify the rendered you wish to use (Fabric or the older renderer).
|
||||
*/
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
return new MainActivityDelegate(this, getMainComponentName());
|
||||
}
|
||||
|
||||
public static class MainActivityDelegate extends ReactActivityDelegate {
|
||||
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
|
||||
super(activity, mainComponentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactRootView createRootView() {
|
||||
ReactRootView reactRootView = new ReactRootView(getContext());
|
||||
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
|
||||
return reactRootView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.facebook.react.ReactInstanceManager;
|
||||
import cl.json.ShareApplication;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
@@ -63,7 +62,7 @@ public class MainApplication extends Application implements ReactApplication, Sh
|
||||
We use reflection here to pick up the class that initializes Flipper,
|
||||
since Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("com.drip.ReactNativeFlipper");
|
||||
Class<?> aClass = Class.forName("com.rndiffapp.ReactNativeFlipper");
|
||||
aClass
|
||||
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||
.invoke(null, context, reactInstanceManager);
|
||||
|
||||
@@ -14,5 +14,4 @@
|
||||
<color name="grey">#A5A5A5</color>
|
||||
<color name="orange">#F38337</color>
|
||||
<color name="purple">#3A2671</color>
|
||||
<color name="turquoiseDark">#69CBC1</color>
|
||||
</resources>
|
||||
@@ -1,5 +1,3 @@
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
@@ -7,14 +5,13 @@ buildscript {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
ext.kotlinVersion = '1.3.40'
|
||||
ext.kotlinVersion = "1.3.10"
|
||||
dependencies {
|
||||
classpath('com.android.tools.build:gradle:7.0.4')
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("de.undercouch:gradle-download-task:4.1.2")
|
||||
classpath("com.android.tools.build:gradle:4.2.2")
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,17 +46,12 @@ allprojects {
|
||||
}
|
||||
|
||||
ext {
|
||||
buildToolsVersion = "33.0.2"
|
||||
minSdkVersion = 21
|
||||
compileSdkVersion = 33
|
||||
targetSdkVersion = 33
|
||||
soLoaderVersion = "0.10.4+"
|
||||
googlePlayServicesVersion = "+" // default: "+"
|
||||
firebaseMessagingVersion = "21.1.0" // default: "+"
|
||||
|
||||
if (System.properties['os.arch'] == "aarch64") {
|
||||
// For M1 Users we need to use the NDK 24 which added support for aarch64
|
||||
ndkVersion = "24.0.8215888"
|
||||
} else {
|
||||
// Otherwise we default to the side-by-side NDK version from AGP.
|
||||
ndkVersion = "21.4.7075529"
|
||||
}
|
||||
buildToolsVersion = "30.0.2"
|
||||
minSdkVersion = 23
|
||||
compileSdkVersion = 30
|
||||
targetSdkVersion = 30
|
||||
ndkVersion = "21.4.7075529"
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
|
||||
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
|
||||
# Default value: -Xmx1024m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
@@ -25,16 +25,7 @@ android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.125.0
|
||||
FLIPPER_VERSION=0.99.0
|
||||
|
||||
# Use this property to specify which architecture you want to build.
|
||||
# You can also override it from the CLI using
|
||||
# ./gradlew <task> -PreactNativeArchitectures=x86_64
|
||||
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
|
||||
|
||||
# Use this property to enable support to the new architecture.
|
||||
# This will allow you to use TurboModules and the Fabric render in
|
||||
# your application. You should enable this flag either if you want
|
||||
# to write custom TurboModules/Fabric components OR use libraries that
|
||||
# are providing them.
|
||||
newArchEnabled=false
|
||||
# https://github.com/facebook/react-native/issues/30729
|
||||
org.gradle.jvmargs=-Xmx4g
|
||||
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -17,103 +17,70 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
} >&2
|
||||
}
|
||||
|
||||
die () {
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
@@ -121,9 +88,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -132,7 +99,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@@ -140,95 +107,80 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
@@ -3,10 +3,3 @@ rootProject.name = 'drip'
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
|
||||
include ':app'
|
||||
|
||||
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||
|
||||
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
|
||||
include(":ReactAndroid")
|
||||
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
|
||||
}
|
||||
|
||||
@@ -14,10 +14,6 @@ import {
|
||||
determinePredictionText,
|
||||
formatWithOrdinalSuffix,
|
||||
} from './helpers/home'
|
||||
import {
|
||||
fertilityTrackingObservable,
|
||||
periodPredictionObservable,
|
||||
} from '../local-storage'
|
||||
|
||||
import { Colors, Fonts, Sizes, Spacing } from '../styles'
|
||||
import { LocalDate } from '@js-joda/core'
|
||||
@@ -31,13 +27,11 @@ const Home = ({ navigate, setDate }) => {
|
||||
navigate('CycleDay')
|
||||
}
|
||||
|
||||
const isFertilityTrackingEnabled = fertilityTrackingObservable.value
|
||||
const todayDateString = LocalDate.now().toString()
|
||||
const { getCycleDayNumber, getPredictedMenses } = cycleModule()
|
||||
const cycleDayNumber = getCycleDayNumber(todayDateString)
|
||||
const { status, phase, statusText } =
|
||||
isFertilityTrackingEnabled && getFertilityStatusForDay(todayDateString)
|
||||
const isPeriodPredictionEnabled = periodPredictionObservable.value
|
||||
getFertilityStatusForDay(todayDateString)
|
||||
const prediction = determinePredictionText(getPredictedMenses(), t)
|
||||
|
||||
const cycleDayText = cycleDayNumber
|
||||
@@ -51,7 +45,6 @@ const Home = ({ navigate, setDate }) => {
|
||||
>
|
||||
<AppText style={styles.title}>{moment().format('MMM Do YYYY')}</AppText>
|
||||
|
||||
{/* display if at least 1 bleeding day has been entered */}
|
||||
{cycleDayNumber && (
|
||||
<View style={styles.line}>
|
||||
<AppText style={styles.whiteSubtitle}>{cycleDayText}</AppText>
|
||||
@@ -60,9 +53,7 @@ const Home = ({ navigate, setDate }) => {
|
||||
</AppText>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* display if fertility tracking enabled and if phase 1, 2 or 3 has been identified */}
|
||||
{isFertilityTrackingEnabled && phase && (
|
||||
{phase && (
|
||||
<View style={styles.line}>
|
||||
<AppText style={styles.whiteSubtitle}>
|
||||
{formatWithOrdinalSuffix(phase)}
|
||||
@@ -74,14 +65,9 @@ const Home = ({ navigate, setDate }) => {
|
||||
<Asterisk />
|
||||
</View>
|
||||
)}
|
||||
|
||||
{isPeriodPredictionEnabled && (
|
||||
<View style={styles.line}>
|
||||
<AppText style={styles.turquoiseText}>{prediction}</AppText>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{!isFertilityTrackingEnabled && <View style={styles.largePadding}></View>}
|
||||
<View style={styles.line}>
|
||||
<AppText style={styles.turquoiseText}>{prediction}</AppText>
|
||||
</View>
|
||||
<Button isCTA isSmall={false} onPress={navigateToCycleDayView}>
|
||||
{t('labels.home.addDataForToday')}
|
||||
</Button>
|
||||
@@ -120,9 +106,6 @@ const styles = StyleSheet.create({
|
||||
color: 'white',
|
||||
fontSize: Sizes.subtitle,
|
||||
},
|
||||
largePadding: {
|
||||
padding: Spacing.large,
|
||||
},
|
||||
})
|
||||
|
||||
Home.propTypes = {
|
||||
|
||||
@@ -4,19 +4,15 @@ import { StyleSheet, View } from 'react-native'
|
||||
|
||||
import AppText from '../common/app-text'
|
||||
|
||||
import { Sizes, Typography } from '../../styles'
|
||||
import { Typography } from '../../styles'
|
||||
import { CHART_YAXIS_WIDTH } from '../../config'
|
||||
import { shared as labels } from '../../i18n/en/labels'
|
||||
|
||||
const ChartLegend = ({ height }) => {
|
||||
return (
|
||||
<View style={[styles.container, { height }]}>
|
||||
<View style={[styles.singleLabelContainer, { height: height / 2 }]}>
|
||||
<AppText style={styles.textBold}>#</AppText>
|
||||
</View>
|
||||
<View style={[styles.singleLabelContainer, { height: height / 2 }]}>
|
||||
<AppText style={styles.text}>{labels.date}</AppText>
|
||||
</View>
|
||||
<AppText style={styles.textBold}>#</AppText>
|
||||
<AppText style={styles.text}>{labels.date}</AppText>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -31,13 +27,8 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'flex-end',
|
||||
width: CHART_YAXIS_WIDTH,
|
||||
},
|
||||
singleLabelContainer: {
|
||||
justifyContent: 'space-around',
|
||||
alignItems: 'center',
|
||||
},
|
||||
text: {
|
||||
...Typography.label,
|
||||
fontSize: Sizes.footnote,
|
||||
},
|
||||
textBold: {
|
||||
...Typography.labelBold,
|
||||
|
||||
@@ -13,18 +13,7 @@ import Tutorial from './Tutorial'
|
||||
import YAxis from './y-axis'
|
||||
|
||||
import { getCycleDaysSortedByDate } from '../../db'
|
||||
import {
|
||||
getChartFlag,
|
||||
setChartFlag,
|
||||
desireTrackingCategoryObservable,
|
||||
moodTrackingCategoryObservable,
|
||||
noteTrackingCategoryObservable,
|
||||
painTrackingCategoryObservable,
|
||||
sexTrackingCategoryObservable,
|
||||
temperatureTrackingCategoryObservable,
|
||||
mucusTrackingCategoryObservable,
|
||||
cervixTrackingCategoryObservable,
|
||||
} from '../../local-storage'
|
||||
import { getChartFlag, setChartFlag } from '../../local-storage'
|
||||
import { makeColumnInfo } from '../helpers/chart'
|
||||
|
||||
import {
|
||||
@@ -40,7 +29,7 @@ const getSymptomsFromCycleDays = (cycleDays) =>
|
||||
SYMPTOMS.filter((symptom) => cycleDays.some((cycleDay) => cycleDay[symptom]))
|
||||
|
||||
const CycleChart = ({ navigate, setDate }) => {
|
||||
const [shouldShowHint, setShouldShowHint] = useState(false)
|
||||
const [shouldShowHint, setShouldShowHint] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true
|
||||
@@ -71,31 +60,7 @@ const CycleChart = ({ navigate, setDate }) => {
|
||||
(symptom) => symptom !== 'temperature'
|
||||
)
|
||||
|
||||
const symptomRowEnabledSymptoms = symptomRowSymptoms.filter((symptom) => {
|
||||
if (symptom === 'sex') {
|
||||
return sexTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'mucus') {
|
||||
return mucusTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'cervix') {
|
||||
return cervixTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'desire') {
|
||||
return desireTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'pain') {
|
||||
return painTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'mood') {
|
||||
return moodTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'note') {
|
||||
return noteTrackingCategoryObservable.value ? symptom : null
|
||||
} else {
|
||||
return symptom
|
||||
}
|
||||
})
|
||||
|
||||
const isTemperatureEnabled = temperatureTrackingCategoryObservable.value
|
||||
const shouldShowTemperatureColumn =
|
||||
isTemperatureEnabled && chartSymptoms.indexOf('temperature') > -1
|
||||
const shouldShowNoDataWarning =
|
||||
isTemperatureEnabled && chartSymptoms.indexOf('temperature') <= -1
|
||||
const shouldShowTemperatureColumn = chartSymptoms.indexOf('temperature') > -1
|
||||
|
||||
const { width, height } = Dimensions.get('window')
|
||||
const numberOfColumnsToRender = Math.round(width / CHART_COLUMN_WIDTH)
|
||||
@@ -106,9 +71,8 @@ const CycleChart = ({ navigate, setDate }) => {
|
||||
remainingHeight * CHART_SYMPTOM_HEIGHT_RATIO
|
||||
)
|
||||
const symptomRowHeight =
|
||||
PixelRatio.roundToNearestPixel(
|
||||
symptomRowEnabledSymptoms.length * symptomHeight
|
||||
) + CHART_GRID_LINE_HORIZONTAL_WIDTH
|
||||
PixelRatio.roundToNearestPixel(symptomRowSymptoms.length * symptomHeight) +
|
||||
CHART_GRID_LINE_HORIZONTAL_WIDTH
|
||||
const columnHeight = remainingHeight - symptomRowHeight
|
||||
|
||||
const chartHeight = shouldShowTemperatureColumn
|
||||
@@ -125,7 +89,7 @@ const CycleChart = ({ navigate, setDate }) => {
|
||||
navigate={navigate}
|
||||
symptomHeight={symptomHeight}
|
||||
columnHeight={columnHeight}
|
||||
symptomRowSymptoms={symptomRowEnabledSymptoms}
|
||||
symptomRowSymptoms={symptomRowSymptoms}
|
||||
chartSymptoms={chartSymptoms}
|
||||
shouldShowTemperatureColumn={shouldShowTemperatureColumn}
|
||||
xAxisHeight={xAxisHeight}
|
||||
@@ -146,11 +110,11 @@ const CycleChart = ({ navigate, setDate }) => {
|
||||
>
|
||||
<View style={styles.chartContainer}>
|
||||
{shouldShowHint && <Tutorial onClose={hideHint} />}
|
||||
{shouldShowNoDataWarning && <NoTemperature />}
|
||||
{!shouldShowTemperatureColumn && <NoTemperature />}
|
||||
<View style={styles.chartArea}>
|
||||
<YAxis
|
||||
height={columnHeight}
|
||||
symptomsToDisplay={symptomRowEnabledSymptoms}
|
||||
symptomsToDisplay={symptomRowSymptoms}
|
||||
symptomsSectionHeight={symptomRowHeight}
|
||||
shouldShowTemperatureColumn={shouldShowTemperatureColumn}
|
||||
xAxisHeight={xAxisHeight}
|
||||
|
||||
@@ -19,20 +19,11 @@ const CycleDayLabel = ({ height, date }) => {
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { height }]}>
|
||||
<View style={{ ...styles.labelRow, height: height / 2 }}>
|
||||
<AppText style={styles.textBold}>{cycleDayLabel}</AppText>
|
||||
</View>
|
||||
|
||||
<View style={{ ...styles.labelRow, height: height / 2 }}>
|
||||
{isFirstDayOfMonth && (
|
||||
<AppText style={styles.textFootnote}>
|
||||
{momentDate.format('MMM')}
|
||||
</AppText>
|
||||
)}
|
||||
|
||||
{!isFirstDayOfMonth && (
|
||||
<AppText style={styles.textSmall}>{dayOfMonth}</AppText>
|
||||
)}
|
||||
<AppText style={styles.textBold}>{cycleDayLabel}</AppText>
|
||||
<View style={styles.dateLabel}>
|
||||
<AppText style={styles.text}>
|
||||
{isFirstDayOfMonth ? momentDate.format('MMM') : dayOfMonth}
|
||||
</AppText>
|
||||
{!isFirstDayOfMonth && (
|
||||
<AppText style={styles.textLight}>
|
||||
{getOrdinalSuffix(dayOfMonth)}
|
||||
@@ -54,21 +45,17 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'flex-end',
|
||||
left: 4,
|
||||
},
|
||||
textSmall: {
|
||||
text: {
|
||||
...Typography.label,
|
||||
fontSize: Sizes.small,
|
||||
},
|
||||
textFootnote: {
|
||||
...Typography.label,
|
||||
fontSize: Sizes.footnote,
|
||||
},
|
||||
textBold: {
|
||||
...Typography.labelBold,
|
||||
},
|
||||
textLight: {
|
||||
...Typography.labelLight,
|
||||
},
|
||||
labelRow: {
|
||||
dateLabel: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
alignItems: 'center',
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { TouchableOpacity } from 'react-native'
|
||||
import moment from 'moment'
|
||||
|
||||
import { getCycleDay } from '../../db'
|
||||
|
||||
@@ -27,8 +26,6 @@ const DayColumn = ({
|
||||
symptomRowSymptoms,
|
||||
xAxisHeight,
|
||||
}) => {
|
||||
const momentDate = moment(dateString)
|
||||
const isWeekend = momentDate.day() == 0 || momentDate.day() == 6
|
||||
const cycleDayData = getCycleDay(dateString)
|
||||
let data = {}
|
||||
|
||||
@@ -76,7 +73,6 @@ const DayColumn = ({
|
||||
isVerticalLine={fhmAndLtl.drawFhmLine}
|
||||
data={data && data.temperature}
|
||||
columnHeight={columnHeight}
|
||||
isWeekend={isWeekend}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -96,7 +92,6 @@ const DayColumn = ({
|
||||
isSymptomDataComplete={
|
||||
hasSymptomData && isSymptomDataComplete(symptom, dateString)
|
||||
}
|
||||
isWeekend={isWeekend}
|
||||
height={symptomHeight}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -7,8 +7,7 @@ import { Colors } from '../../styles'
|
||||
import {
|
||||
CHART_COLUMN_WIDTH,
|
||||
CHART_COLUMN_MIDDLE,
|
||||
CHART_DOT_RADIUS_SYMPTOM,
|
||||
CHART_DOT_RADIUS_TEMPERATURE,
|
||||
CHART_DOT_RADIUS,
|
||||
CHART_STROKE_WIDTH,
|
||||
} from '../../config'
|
||||
|
||||
@@ -36,9 +35,9 @@ const DotAndLine = ({
|
||||
}
|
||||
|
||||
const dot = new Path()
|
||||
.moveTo(CHART_COLUMN_MIDDLE, y - CHART_DOT_RADIUS_TEMPERATURE)
|
||||
.arc(0, CHART_DOT_RADIUS_TEMPERATURE * 2, CHART_DOT_RADIUS_TEMPERATURE)
|
||||
.arc(0, CHART_DOT_RADIUS_TEMPERATURE * -2, CHART_DOT_RADIUS_TEMPERATURE)
|
||||
.moveTo(CHART_COLUMN_MIDDLE, y - CHART_DOT_RADIUS)
|
||||
.arc(0, CHART_DOT_RADIUS * 2, CHART_DOT_RADIUS)
|
||||
.arc(0, CHART_DOT_RADIUS * -2, CHART_DOT_RADIUS)
|
||||
const dotColor = exclude ? Colors.turquoise : Colors.turquoiseDark
|
||||
const lineColorLeft = excludeLeftLine
|
||||
? Colors.turquoise
|
||||
@@ -59,13 +58,13 @@ const DotAndLine = ({
|
||||
d={lineRight}
|
||||
stroke={lineColorRight}
|
||||
strokeWidth={CHART_STROKE_WIDTH}
|
||||
key={y + CHART_DOT_RADIUS_SYMPTOM}
|
||||
key={y + CHART_DOT_RADIUS}
|
||||
/>
|
||||
<Shape
|
||||
d={dot}
|
||||
stroke={dotColor}
|
||||
strokeWidth={CHART_STROKE_WIDTH}
|
||||
fill={dotColor}
|
||||
fill="white"
|
||||
key="dot"
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { StyleSheet, View } from 'react-native'
|
||||
import { Colors, Containers } from '../../styles'
|
||||
import {
|
||||
CHART_COLUMN_WIDTH,
|
||||
CHART_DOT_RADIUS_SYMPTOM,
|
||||
CHART_DOT_RADIUS,
|
||||
CHART_GRID_LINE_HORIZONTAL_WIDTH,
|
||||
} from '../../config'
|
||||
|
||||
@@ -15,31 +15,14 @@ const SymptomCell = ({
|
||||
symptom,
|
||||
symptomValue,
|
||||
isSymptomDataComplete,
|
||||
isWeekend,
|
||||
}) => {
|
||||
const shouldDrawDot = symptomValue !== false
|
||||
// Determine the background color based on isWeekend prop
|
||||
const backgroundColor = isWeekend ? Colors.greyVeryLight : 'white'
|
||||
const styleCell =
|
||||
index !== 0
|
||||
? [
|
||||
styles.cell,
|
||||
{
|
||||
height,
|
||||
width: CHART_COLUMN_WIDTH,
|
||||
backgroundColor: backgroundColor,
|
||||
},
|
||||
]
|
||||
: [
|
||||
styles.cell,
|
||||
{
|
||||
height,
|
||||
width: CHART_COLUMN_WIDTH,
|
||||
backgroundColor: backgroundColor,
|
||||
},
|
||||
styles.topBorder,
|
||||
]
|
||||
? [styles.cell, { height, width: CHART_COLUMN_WIDTH }]
|
||||
: [styles.cell, { height, width: CHART_COLUMN_WIDTH }, styles.topBorder]
|
||||
let styleDot
|
||||
|
||||
if (shouldDrawDot) {
|
||||
const styleSymptom = Colors.iconColors[symptom]
|
||||
const symptomColor = styleSymptom.shades[symptomValue]
|
||||
@@ -64,11 +47,11 @@ SymptomCell.propTypes = {
|
||||
symptom: PropTypes.string,
|
||||
symptomValue: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
|
||||
isSymptomDataComplete: PropTypes.bool,
|
||||
isWeekend: PropTypes.bool,
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
cell: {
|
||||
backgroundColor: 'white',
|
||||
borderBottomColor: Colors.grey,
|
||||
borderBottomWidth: CHART_GRID_LINE_HORIZONTAL_WIDTH,
|
||||
borderLeftColor: Colors.grey,
|
||||
@@ -80,8 +63,8 @@ const styles = StyleSheet.create({
|
||||
borderTopWidth: CHART_GRID_LINE_HORIZONTAL_WIDTH,
|
||||
},
|
||||
dot: {
|
||||
width: CHART_DOT_RADIUS_SYMPTOM * 2,
|
||||
height: CHART_DOT_RADIUS_SYMPTOM * 2,
|
||||
width: CHART_DOT_RADIUS * 2,
|
||||
height: CHART_DOT_RADIUS * 2,
|
||||
borderRadius: 50,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Colors } from '../../styles'
|
||||
import { StyleSheet } from 'react-native'
|
||||
|
||||
import { Surface, Path } from '@react-native-community/art'
|
||||
|
||||
@@ -14,16 +14,14 @@ const TemperatureColumn = ({
|
||||
isVerticalLine,
|
||||
data,
|
||||
columnHeight,
|
||||
isWeekend,
|
||||
}) => {
|
||||
const x = CHART_STROKE_WIDTH / 2
|
||||
|
||||
const backgroundColor = isWeekend ? Colors.greyVeryLight : 'white'
|
||||
return (
|
||||
<Surface
|
||||
width={CHART_COLUMN_WIDTH}
|
||||
height={columnHeight}
|
||||
style={{ backgroundColor: backgroundColor }}
|
||||
style={styles.container}
|
||||
>
|
||||
<ChartLine path={new Path().lineTo(0, columnHeight)} />
|
||||
|
||||
@@ -65,7 +63,12 @@ TemperatureColumn.propTypes = {
|
||||
isVerticalLine: PropTypes.bool,
|
||||
data: PropTypes.object,
|
||||
columnHeight: PropTypes.number,
|
||||
isWeekend: PropTypes.bool,
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
})
|
||||
|
||||
export default TemperatureColumn
|
||||
|
||||
@@ -8,15 +8,13 @@ import { Sizes } from '../../styles'
|
||||
import { CHART_TICK_WIDTH } from '../../config'
|
||||
|
||||
const Tick = ({ yPosition, height, isBold, shouldShowLabel, label }) => {
|
||||
const top = yPosition - height / 2 - 4
|
||||
const top = yPosition - height / 2
|
||||
const containerStyle = [styles.container, { flexBasis: height, height, top }]
|
||||
const textStyle = isBold ? styles.textBold : styles.textNormal
|
||||
|
||||
if (!shouldShowLabel) return null
|
||||
|
||||
return (
|
||||
<View style={containerStyle}>
|
||||
<AppText style={textStyle}>{label}</AppText>
|
||||
<AppText style={textStyle}>{shouldShowLabel && label}</AppText>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -38,7 +36,6 @@ const styles = StyleSheet.create({
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
width: CHART_TICK_WIDTH,
|
||||
minHeight: Sizes.base + 2,
|
||||
},
|
||||
textBold: {
|
||||
fontSize: Sizes.base,
|
||||
|
||||
@@ -1,25 +1,18 @@
|
||||
import React from 'react'
|
||||
import { Platform, StyleSheet, Switch, View } from 'react-native'
|
||||
import { StyleSheet, Switch, View } from 'react-native'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import AppText from './app-text'
|
||||
|
||||
import { Colors, Containers, Spacing } from '../../styles'
|
||||
import { Containers } from '../../styles'
|
||||
|
||||
const AppSwitch = ({ onToggle, text, value, disabled }) => {
|
||||
const trackColor = { true: Colors.turquoiseDark }
|
||||
const AppSwitch = ({ onToggle, text, value }) => {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.textContainer}>
|
||||
<AppText>{text}</AppText>
|
||||
</View>
|
||||
<Switch
|
||||
onValueChange={onToggle}
|
||||
style={styles.switch}
|
||||
value={value}
|
||||
trackColor={trackColor}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<Switch onValueChange={onToggle} style={styles.switch} value={value} />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -28,20 +21,14 @@ AppSwitch.propTypes = {
|
||||
onToggle: PropTypes.func.isRequired,
|
||||
text: PropTypes.string,
|
||||
value: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
...Containers.rowContainer,
|
||||
marginTop: Spacing.tiny,
|
||||
},
|
||||
switch: {
|
||||
flex: 1,
|
||||
transform:
|
||||
Platform.OS === 'ios'
|
||||
? [{ scaleX: 0.8 }, { scaleY: 0.8 }]
|
||||
: [{ scaleX: 1 }, { scaleY: 1 }],
|
||||
},
|
||||
textContainer: {
|
||||
flex: 4,
|
||||
|
||||
@@ -6,14 +6,13 @@ import AppText from './app-text'
|
||||
|
||||
import { Colors, Containers, Spacing, Typography } from '../../styles'
|
||||
|
||||
const Segment = ({ children, last, title, subheader }) => {
|
||||
const Segment = ({ children, last, title }) => {
|
||||
const containerStyle = last ? styles.containerLast : styles.container
|
||||
const commonStyle = Object.assign({}, containerStyle)
|
||||
|
||||
return (
|
||||
<View style={commonStyle}>
|
||||
{title && <AppText style={styles.title}>{title}</AppText>}
|
||||
{subheader && <AppText style={styles.subheader}>{subheader}</AppText>}
|
||||
{children}
|
||||
</View>
|
||||
)
|
||||
@@ -24,7 +23,6 @@ Segment.propTypes = {
|
||||
last: PropTypes.bool,
|
||||
style: PropTypes.object,
|
||||
title: PropTypes.string,
|
||||
subheader: PropTypes.string,
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@@ -41,11 +39,6 @@ const styles = StyleSheet.create({
|
||||
title: {
|
||||
...Typography.subtitle,
|
||||
},
|
||||
subheader: {
|
||||
...Typography.subtitle,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: Spacing.zero,
|
||||
},
|
||||
})
|
||||
|
||||
export default Segment
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Platform, StyleSheet, Switch, View } from 'react-native'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import AppText from './app-text'
|
||||
|
||||
import DripIcon from '../../assets/drip-icons'
|
||||
import { Colors, Containers, Sizes, Spacing } from '../../styles'
|
||||
|
||||
const TrackingCategorySwitch = ({ onToggle, symptom, text, value }) => {
|
||||
const trackColor = { true: Colors.turquoiseDark }
|
||||
const iconColor = value ? Colors.iconColors[symptom].color : Colors.grey
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.iconContainer}>
|
||||
<DripIcon
|
||||
color={iconColor}
|
||||
name={`drip-icon-${symptom}`}
|
||||
size={Sizes.title}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.textContainer}>
|
||||
<AppText>{text}</AppText>
|
||||
</View>
|
||||
<Switch
|
||||
onValueChange={onToggle}
|
||||
style={styles.appSwitch}
|
||||
value={value}
|
||||
trackColor={trackColor}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
TrackingCategorySwitch.propTypes = {
|
||||
onToggle: PropTypes.func.isRequired,
|
||||
symptom: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
value: PropTypes.bool,
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
...Containers.rowContainer,
|
||||
marginVertical: Spacing.tiny,
|
||||
},
|
||||
iconContainer: {
|
||||
marginRight: Spacing.tiny,
|
||||
flex: 1,
|
||||
},
|
||||
textContainer: {
|
||||
flex: 5,
|
||||
},
|
||||
appSwitch: {
|
||||
flex: 2,
|
||||
transform:
|
||||
Platform.OS === 'ios'
|
||||
? [{ scaleX: 0.8 }, { scaleY: 0.8 }]
|
||||
: [{ scaleX: 1 }, { scaleY: 1 }],
|
||||
},
|
||||
})
|
||||
export default TrackingCategorySwitch
|
||||
@@ -9,16 +9,6 @@ import SymptomPageTitle from './symptom-page-title'
|
||||
import { getCycleDay } from '../../db'
|
||||
import { getData, nextDate, prevDate } from '../helpers/cycle-day'
|
||||
|
||||
import {
|
||||
desireTrackingCategoryObservable,
|
||||
moodTrackingCategoryObservable,
|
||||
noteTrackingCategoryObservable,
|
||||
painTrackingCategoryObservable,
|
||||
sexTrackingCategoryObservable,
|
||||
temperatureTrackingCategoryObservable,
|
||||
mucusTrackingCategoryObservable,
|
||||
cervixTrackingCategoryObservable,
|
||||
} from '../../local-storage'
|
||||
import { Spacing } from '../../styles'
|
||||
import { SYMPTOMS } from '../../config'
|
||||
|
||||
@@ -37,29 +27,6 @@ const CycleDayOverView = ({ date, setDate, isTemperatureEditView }) => {
|
||||
setDate(prevDate(date))
|
||||
}
|
||||
|
||||
const allEnabledSymptoms = SYMPTOMS.map((symptom) => {
|
||||
if (symptom === 'temperature') {
|
||||
return temperatureTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'sex') {
|
||||
return sexTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'mucus') {
|
||||
return mucusTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'cervix') {
|
||||
return cervixTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'desire') {
|
||||
return desireTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'pain') {
|
||||
return painTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'mood') {
|
||||
return moodTrackingCategoryObservable.value ? symptom : null
|
||||
} else if (symptom === 'note') {
|
||||
return noteTrackingCategoryObservable.value ? symptom : null
|
||||
} else {
|
||||
return symptom
|
||||
}
|
||||
})
|
||||
const cleanSymptoms = allEnabledSymptoms.filter(Boolean)
|
||||
|
||||
return (
|
||||
<AppPage>
|
||||
<SymptomPageTitle
|
||||
@@ -68,7 +35,7 @@ const CycleDayOverView = ({ date, setDate, isTemperatureEditView }) => {
|
||||
onPrevCycleDay={showPrevCycleDay}
|
||||
/>
|
||||
<View style={styles.container}>
|
||||
{cleanSymptoms.map((symptom) => {
|
||||
{SYMPTOMS.map((symptom) => {
|
||||
const symptomData =
|
||||
cycleDay && cycleDay[symptom] ? cycleDay[symptom] : null
|
||||
|
||||
|
||||
@@ -1,61 +1,22 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Alert, StyleSheet, TouchableOpacity, View } from 'react-native'
|
||||
import { StyleSheet, TouchableOpacity, View } from 'react-native'
|
||||
|
||||
import AppText from '../common/app-text'
|
||||
|
||||
import { Colors, Containers } from '../../styles'
|
||||
import labels from '../../i18n/en/settings'
|
||||
|
||||
export default function SelectTabGroup({
|
||||
activeButton,
|
||||
buttons,
|
||||
onSelect,
|
||||
disabled,
|
||||
}) {
|
||||
// TODO https://gitlab.com/bloodyhealth/drip/-/issues/707
|
||||
const oneTimeTransformIntoNumber =
|
||||
typeof activeButton === 'boolean' && Number(activeButton)
|
||||
const isSecondarySymptomSwitch =
|
||||
buttons[0]['label'] === labels.secondarySymptom.mucus
|
||||
|
||||
// Disable is only used for secondarySymptom in customization, if more come up maybe consider more tidy solution
|
||||
const showDisabledAlert = (label) => {
|
||||
if (
|
||||
label === labels.secondarySymptom.cervix ||
|
||||
label === labels.secondarySymptom.mucus
|
||||
) {
|
||||
Alert.alert(
|
||||
labels.secondarySymptom.disabled.title,
|
||||
labels.secondarySymptom.disabled.message
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default function SelectTabGroup({ activeButton, buttons, onSelect }) {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{buttons.map(({ label, value }, i) => {
|
||||
const isActive =
|
||||
value === activeButton || value === oneTimeTransformIntoNumber
|
||||
const boxStyle = [
|
||||
styles.box,
|
||||
isActive && styles.boxActive,
|
||||
isSecondarySymptomSwitch && styles.purpleBox,
|
||||
isSecondarySymptomSwitch && isActive && styles.activePurpleBox,
|
||||
disabled && styles.disabledBox,
|
||||
]
|
||||
const textStyle = [
|
||||
styles.text,
|
||||
isSecondarySymptomSwitch && styles.purpleText,
|
||||
isActive && styles.textActive,
|
||||
disabled && styles.greyText,
|
||||
]
|
||||
const isActive = value === activeButton
|
||||
const boxStyle = [styles.box, isActive && styles.boxActive]
|
||||
const textStyle = [styles.text, isActive && styles.textActive]
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() =>
|
||||
!disabled ? onSelect(value) : showDisabledAlert(label)
|
||||
}
|
||||
onPress={() => onSelect(value)}
|
||||
key={i}
|
||||
style={boxStyle}
|
||||
>
|
||||
@@ -71,7 +32,6 @@ SelectTabGroup.propTypes = {
|
||||
activeButton: PropTypes.number,
|
||||
buttons: PropTypes.array.isRequired,
|
||||
onSelect: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@@ -90,20 +50,4 @@ const styles = StyleSheet.create({
|
||||
textActive: {
|
||||
color: 'white',
|
||||
},
|
||||
purpleBox: {
|
||||
borderColor: Colors.purple,
|
||||
},
|
||||
activePurpleBox: {
|
||||
backgroundColor: Colors.purple,
|
||||
},
|
||||
purpleText: {
|
||||
color: Colors.purple,
|
||||
},
|
||||
greyText: {
|
||||
color: Colors.grey,
|
||||
},
|
||||
disabledBox: {
|
||||
borderColor: Colors.grey,
|
||||
backgroundColor: Colors.turquoiseLight,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -20,7 +20,7 @@ const SymptomBox = ({
|
||||
editedSymptom,
|
||||
setEditedSymptom,
|
||||
}) => {
|
||||
const { t } = useTranslation(null, { keyPrefix: 'symptoms' })
|
||||
const { t } = useTranslation(null, { keyPrefix: 'cycleDay.symptomBox' })
|
||||
const isSymptomEdited = editedSymptom === symptom
|
||||
const isSymptomDisabled = isDateInFuture(date) && symptom !== 'note'
|
||||
const isExcluded = symptomData !== null ? symptomData.exclude : false
|
||||
|
||||
@@ -15,7 +15,6 @@ import Temperature from './temperature'
|
||||
import { blank, save, shouldShow, symtomPage } from '../helpers/cycle-day'
|
||||
import { showToast } from '../helpers/general'
|
||||
|
||||
import { fertilityTrackingObservable } from '../../local-storage'
|
||||
import { shared as sharedLabels } from '../../i18n/en/labels'
|
||||
import info from '../../i18n/en/symptom-info'
|
||||
import { Colors, Containers, Sizes, Spacing } from '../../styles'
|
||||
@@ -26,7 +25,6 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
|
||||
const [shouldShowInfo, setShouldShowInfo] = useState(false)
|
||||
const getParsedData = () => JSON.parse(JSON.stringify(data))
|
||||
const onPressLearnMore = () => setShouldShowInfo(!shouldShowInfo)
|
||||
const isFertilityTrackingEnabled = fertilityTrackingObservable.value
|
||||
|
||||
const onEditNote = (note) => {
|
||||
const parsedData = getParsedData()
|
||||
@@ -104,7 +102,8 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
|
||||
const onSelectTab = (group, value) => {
|
||||
const parsedData = getParsedData()
|
||||
|
||||
parsedData[group.key] = parsedData[group.key] !== value ? value : null
|
||||
Object.assign(parsedData, { [group.key]: value })
|
||||
|
||||
setData(parsedData)
|
||||
}
|
||||
const iconName = shouldShowInfo ? 'chevron-up' : 'chevron-down'
|
||||
@@ -169,18 +168,15 @@ const SymptomEditView = ({ date, onClose, symptom, symptomData }) => {
|
||||
</Segment>
|
||||
)
|
||||
})}
|
||||
{/* show exclude AppSwitch for bleeding, mucus, cervix, temperature */}
|
||||
{/* but if fertility is off only for bleeding */}
|
||||
{shouldShow(symptomConfig.excludeText) &&
|
||||
(symptom === 'bleeding' || isFertilityTrackingEnabled) && (
|
||||
<Segment style={styles.segmentBorder}>
|
||||
<AppSwitch
|
||||
onToggle={onExcludeToggle}
|
||||
text={symtomPage[symptom].excludeText}
|
||||
value={data.exclude}
|
||||
/>
|
||||
</Segment>
|
||||
)}
|
||||
{shouldShow(symptomConfig.excludeText) && (
|
||||
<Segment style={styles.segmentBorder}>
|
||||
<AppSwitch
|
||||
onToggle={onExcludeToggle}
|
||||
text={symtomPage[symptom].excludeText}
|
||||
value={data.exclude}
|
||||
/>
|
||||
</Segment>
|
||||
)}
|
||||
{shouldShow(symptomConfig.note) && (
|
||||
<Segment style={styles.segmentBorder}>
|
||||
<AppText>{symtomPage[symptom].note}</AppText>
|
||||
|
||||
@@ -108,7 +108,6 @@ const styles = StyleSheet.create({
|
||||
hint: {
|
||||
fontStyle: 'italic',
|
||||
fontSize: Sizes.small,
|
||||
color: Colors.orange,
|
||||
},
|
||||
hintContainer: {
|
||||
marginVertical: Spacing.tiny,
|
||||
|
||||
@@ -2,7 +2,6 @@ import { LocalDate } from '@js-joda/core'
|
||||
import { verticalScale } from 'react-native-size-matters'
|
||||
|
||||
import { Colors, Fonts, Sizes } from '../../styles'
|
||||
import { periodPredictionObservable } from '../../local-storage'
|
||||
|
||||
const { shades } = Colors.iconColors.bleeding
|
||||
|
||||
@@ -27,7 +26,6 @@ export const toCalFormat = (bleedingDaysSortedByDate) => {
|
||||
}
|
||||
|
||||
export const predictionToCalFormat = (predictedDays) => {
|
||||
if (!periodPredictionObservable.value) return {}
|
||||
if (!predictedDays.length) return {}
|
||||
const todayDateString = LocalDate.now().toString()
|
||||
const middleIndex = (predictedDays[0].length - 1) / 2
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { LocalDate } from '@js-joda/core'
|
||||
|
||||
import {
|
||||
fertilityTrackingObservable,
|
||||
scaleObservable,
|
||||
unitObservable,
|
||||
} from '../../local-storage'
|
||||
import { scaleObservable, unitObservable } from '../../local-storage'
|
||||
import { getCycleStatusForDay } from '../../lib/sympto-adapter'
|
||||
import { getCycleDay, getAmountOfCycleDays } from '../../db'
|
||||
|
||||
@@ -274,8 +270,7 @@ export function nfpLines() {
|
||||
if (dateString < cycle.startDate) updateCurrentCycle(dateString)
|
||||
if (cycle.noMoreCycles) return ret
|
||||
|
||||
const tempShift =
|
||||
fertilityTrackingObservable.value && cycle.status.temperatureShift
|
||||
const tempShift = cycle.status.temperatureShift
|
||||
|
||||
if (tempShift) {
|
||||
if (tempShift.firstHighMeasurementDay.date === dateString) {
|
||||
|
||||
@@ -34,10 +34,6 @@ export const formatTemperature = (temperature) =>
|
||||
? temperature
|
||||
: Number.parseFloat(temperature.toString()).toFixed(2)
|
||||
|
||||
//maximum of precision digits after decimal point, but no x.0
|
||||
export const formatDecimal = (num, precision) =>
|
||||
+parseFloat(Number.parseFloat(num).toFixed(precision))
|
||||
|
||||
export const getPreviousTemperature = (date) => {
|
||||
const previousTemperature = getPreviousTemperatureForDate(date)
|
||||
return formatTemperature(previousTemperature)
|
||||
|
||||
@@ -37,17 +37,13 @@ export const pages = [
|
||||
parent: 'SettingsMenu',
|
||||
},
|
||||
{
|
||||
component: 'Customization',
|
||||
component: 'NfpSettings',
|
||||
parent: 'SettingsMenu',
|
||||
},
|
||||
{
|
||||
component: 'DataManagement',
|
||||
parent: 'SettingsMenu',
|
||||
},
|
||||
{
|
||||
component: 'Info',
|
||||
parent: 'SettingsMenu',
|
||||
},
|
||||
{
|
||||
component: 'Password',
|
||||
parent: 'SettingsMenu',
|
||||
|
||||
@@ -18,10 +18,6 @@ const AboutSection = () => {
|
||||
<AppPage title={t('title')}>
|
||||
<Segment>
|
||||
<AppText>{t('intro.text')}</AppText>
|
||||
<Button isCTA isSmall onPress={() => Linking.openURL(links.faq.url)}>
|
||||
{t('intro.faq')}
|
||||
</Button>
|
||||
<AppText>{t('intro.contact')}</AppText>
|
||||
<ButtonRow>
|
||||
{[links.email, links.gitlab, links.website].map((link) => (
|
||||
<Button
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import React from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import AppIcon from '../common/app-icon'
|
||||
import AppPage from '../common/app-page'
|
||||
import AppText from '../common/app-text'
|
||||
import Segment from '../common/segment'
|
||||
|
||||
import { Colors, Spacing, Typography } from '../../styles'
|
||||
import labels from '../../i18n/en/settings'
|
||||
|
||||
const Info = () => {
|
||||
const { t } = useTranslation(null, { keyPrefix: 'hamburgerMenu.info' })
|
||||
return (
|
||||
<AppPage title={t('title')}>
|
||||
<Segment last>
|
||||
<View style={styles.line}>
|
||||
<AppIcon
|
||||
color={Colors.purple}
|
||||
name="info-with-circle"
|
||||
style={styles.icon}
|
||||
/>
|
||||
<AppText style={styles.title}>{labels.preOvu.title}</AppText>
|
||||
</View>
|
||||
<AppText>{labels.preOvu.note}</AppText>
|
||||
</Segment>
|
||||
</AppPage>
|
||||
)
|
||||
}
|
||||
|
||||
Info.propTypes = {
|
||||
children: PropTypes.node,
|
||||
}
|
||||
|
||||
export default Info
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
icon: {
|
||||
marginRight: Spacing.base,
|
||||
},
|
||||
line: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
title: {
|
||||
...Typography.subtitle,
|
||||
},
|
||||
})
|
||||
@@ -1,20 +1,18 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet } from 'react-native'
|
||||
|
||||
import AppPage from '../common/app-page'
|
||||
import AppText from '../common/app-text'
|
||||
import AppLink from '../common/AppLink'
|
||||
import Segment from '../common/segment'
|
||||
import { Spacing } from '../../styles'
|
||||
|
||||
const License = ({ children }) => {
|
||||
const { t } = useTranslation(null, { keyPrefix: 'hamburgerMenu.license' })
|
||||
const currentYear = new Date().getFullYear()
|
||||
const link = 'https://www.gnu.org/licenses/gpl-3.0.html'
|
||||
return (
|
||||
<AppPage title={t('title')} contentContainerStyle={styles.contentContainer}>
|
||||
<AppPage title={t('title')}>
|
||||
<Segment last>
|
||||
<AppText>{t('text', { currentYear })}</AppText>
|
||||
<AppLink url={link}>{link}</AppLink>
|
||||
@@ -28,10 +26,4 @@ License.propTypes = {
|
||||
children: PropTypes.node,
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
contentContainer: {
|
||||
marginTop: Spacing.large,
|
||||
},
|
||||
})
|
||||
|
||||
export default License
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
import React from 'react'
|
||||
import { View } from 'react-native'
|
||||
import PropTypes from 'prop-types'
|
||||
import Slider from '@ptomasroos/react-native-multi-slider'
|
||||
|
||||
import SliderLabel from './slider-label'
|
||||
import { styles } from './slider-styles'
|
||||
import {
|
||||
ADVANCE_PERIOD_NOTICE_DAYS_MIN,
|
||||
ADVANCE_PERIOD_NOTICE_DAYS_MAX,
|
||||
} from '../../../config'
|
||||
|
||||
const AdvanceNoticeDaysSlider = ({
|
||||
disabled,
|
||||
advanceNoticeDays,
|
||||
onAdvanceNoticeDaysChange,
|
||||
}) => {
|
||||
const sliderAccentBackground = disabled
|
||||
? styles.disabledSliderAccentBackground
|
||||
: styles.sliderAccentBackground
|
||||
|
||||
const sliderBackground = disabled
|
||||
? styles.disabledSliderBackground
|
||||
: styles.sliderBackground
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Slider
|
||||
customLabel={SliderLabel}
|
||||
enableLabel={true}
|
||||
markerStyle={styles.marker}
|
||||
markerOffsetY={styles.markerOffsetY}
|
||||
max={ADVANCE_PERIOD_NOTICE_DAYS_MAX}
|
||||
min={ADVANCE_PERIOD_NOTICE_DAYS_MIN}
|
||||
onValuesChange={onAdvanceNoticeDaysChange}
|
||||
step={1}
|
||||
showSteps={true}
|
||||
snapped={true}
|
||||
trackStyle={styles.slider}
|
||||
values={[advanceNoticeDays]}
|
||||
enabledOne={!disabled}
|
||||
enabledTwo={false}
|
||||
selectedStyle={sliderAccentBackground}
|
||||
unselectedStyle={sliderBackground}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdvanceNoticeDaysSlider
|
||||
|
||||
AdvanceNoticeDaysSlider.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
advanceNoticeDays: PropTypes.number,
|
||||
onAdvanceNoticeDaysChange: PropTypes.func,
|
||||
}
|
||||
@@ -1,351 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Alert, Pressable, StyleSheet, View } from 'react-native'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import AppIcon from '../../common/app-icon'
|
||||
import AppPage from '../../common/app-page'
|
||||
import AppSwitch from '../../common/app-switch'
|
||||
import AppText from '../../common/app-text'
|
||||
import { Colors, Spacing, Typography } from '../../../styles'
|
||||
import TemperatureSlider from './temperature-slider'
|
||||
import Segment from '../../common/segment'
|
||||
import TrackingCategorySwitch from '../../common/tracking-category-switch'
|
||||
import SelectTabGroup from '../../cycle-day/select-tab-group'
|
||||
|
||||
import {
|
||||
desireTrackingCategoryObservable,
|
||||
fertilityTrackingObservable,
|
||||
moodTrackingCategoryObservable,
|
||||
noteTrackingCategoryObservable,
|
||||
painTrackingCategoryObservable,
|
||||
sexTrackingCategoryObservable,
|
||||
temperatureTrackingCategoryObservable,
|
||||
mucusTrackingCategoryObservable,
|
||||
cervixTrackingCategoryObservable,
|
||||
periodPredictionObservable,
|
||||
useCervixAsSecondarySymptomObservable,
|
||||
saveDesireTrackingCategory,
|
||||
saveFertilityTrackingEnabled,
|
||||
saveMoodTrackingCategory,
|
||||
saveNoteTrackingCategory,
|
||||
savePainTrackingCategory,
|
||||
saveMucusTrackingCategory,
|
||||
saveCervixTrackingCategory,
|
||||
savePeriodPrediction,
|
||||
saveSexTrackingCategory,
|
||||
saveTemperatureTrackingCategory,
|
||||
saveUseCervixAsSecondarySymptom,
|
||||
} from '../../../local-storage'
|
||||
import labels from '../../../i18n/en/settings'
|
||||
import { SYMPTOMS } from '../../../config'
|
||||
|
||||
const Settings = () => {
|
||||
const { t } = useTranslation(null, { keyPrefix: 'symptoms' })
|
||||
|
||||
const [useCervixAsSecondarySymptom, setUseCervixAsSecondarySymptom] =
|
||||
useState(useCervixAsSecondarySymptomObservable.value)
|
||||
|
||||
const [isPeriodPredictionEnabled, setPeriodPrediction] = useState(
|
||||
periodPredictionObservable.value
|
||||
)
|
||||
|
||||
const [isTemperatureTrackingCategoryEnabled, setTemperatureTrackingCategory] =
|
||||
useState(temperatureTrackingCategoryObservable.value)
|
||||
|
||||
const [isMucusTrackingCategoryEnabled, setMucusTrackingCategory] = useState(
|
||||
mucusTrackingCategoryObservable.value
|
||||
)
|
||||
|
||||
const [isCervixTrackingCategoryEnabled, setCervixTrackingCategory] = useState(
|
||||
cervixTrackingCategoryObservable.value
|
||||
)
|
||||
|
||||
const [isSexTrackingCategoryEnabled, setSexTrackingCategory] = useState(
|
||||
sexTrackingCategoryObservable.value
|
||||
)
|
||||
|
||||
const [isDesireTrackingCategoryEnabled, setDesireTrackingCategory] = useState(
|
||||
desireTrackingCategoryObservable.value
|
||||
)
|
||||
|
||||
const [isPainTrackingCategoryEnabled, setPainTrackingCategory] = useState(
|
||||
painTrackingCategoryObservable.value
|
||||
)
|
||||
|
||||
const [isMoodTrackingCategoryEnabled, setMoodTrackingCategory] = useState(
|
||||
moodTrackingCategoryObservable.value
|
||||
)
|
||||
|
||||
const [isNoteTrackingCategoryEnabled, setNoteTrackingCategory] = useState(
|
||||
noteTrackingCategoryObservable.value
|
||||
)
|
||||
|
||||
const [isFertilityTrackingEnabled, setFertilityTrackingEnabled] = useState(
|
||||
fertilityTrackingObservable.value
|
||||
)
|
||||
|
||||
const fertilityTrackingToggle = (value) => {
|
||||
setFertilityTrackingEnabled(value)
|
||||
saveFertilityTrackingEnabled(value)
|
||||
}
|
||||
|
||||
const temperatureTrackingCategoryToggle = (value) => {
|
||||
setTemperatureTrackingCategory(value)
|
||||
saveTemperatureTrackingCategory(value)
|
||||
if (!value) {
|
||||
setFertilityTrackingEnabled(false)
|
||||
saveFertilityTrackingEnabled(false)
|
||||
}
|
||||
}
|
||||
const mucusTrackingCategoryToggle = (value) => {
|
||||
manageSecondarySymptom(cervixTrackingCategoryObservable.value, value)
|
||||
}
|
||||
const cervixTrackingCategoryToggle = (value) => {
|
||||
manageSecondarySymptom(value, mucusTrackingCategoryObservable.value)
|
||||
}
|
||||
const sexTrackingCategoryToggle = (value) => {
|
||||
setSexTrackingCategory(value)
|
||||
saveSexTrackingCategory(value)
|
||||
}
|
||||
const desireTrackingCategoryToggle = (value) => {
|
||||
setDesireTrackingCategory(value)
|
||||
saveDesireTrackingCategory(value)
|
||||
}
|
||||
const painTrackingCategoryToggle = (value) => {
|
||||
setPainTrackingCategory(value)
|
||||
savePainTrackingCategory(value)
|
||||
}
|
||||
const moodTrackingCategoryToggle = (value) => {
|
||||
setMoodTrackingCategory(value)
|
||||
saveMoodTrackingCategory(value)
|
||||
}
|
||||
const noteTrackingCategoryToggle = (value) => {
|
||||
setNoteTrackingCategory(value)
|
||||
saveNoteTrackingCategory(value)
|
||||
}
|
||||
const onPeriodPredictionToggle = (value) => {
|
||||
setPeriodPrediction(value)
|
||||
savePeriodPrediction(value)
|
||||
}
|
||||
|
||||
const fertilityTrackingText = isFertilityTrackingEnabled
|
||||
? labels.fertilityTracking.on
|
||||
: labels.fertilityTracking.off
|
||||
|
||||
const periodPredictionText = isPeriodPredictionEnabled
|
||||
? labels.periodPrediction.on
|
||||
: labels.periodPrediction.off
|
||||
|
||||
const secondarySymptomButtons = [
|
||||
{
|
||||
label: labels.secondarySymptom.mucus,
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: labels.secondarySymptom.cervix,
|
||||
value: 1,
|
||||
},
|
||||
]
|
||||
|
||||
const onSelectTab = (value) => {
|
||||
if (isMucusTrackingCategoryEnabled && isCervixTrackingCategoryEnabled) {
|
||||
setUseCervixAsSecondarySymptom(value)
|
||||
saveUseCervixAsSecondarySymptom(value)
|
||||
} else {
|
||||
secondarySymptomDisabledPrompt()
|
||||
}
|
||||
}
|
||||
|
||||
// is needed so secondary symptom is set correct on load
|
||||
useEffect(() => {
|
||||
manageSecondarySymptom(
|
||||
cervixTrackingCategoryObservable.value,
|
||||
mucusTrackingCategoryObservable.value
|
||||
)
|
||||
}, [])
|
||||
|
||||
const manageSecondarySymptom = (cervix, mucus) => {
|
||||
if (!cervix && mucus) {
|
||||
setUseCervixAsSecondarySymptom(0)
|
||||
saveUseCervixAsSecondarySymptom(0)
|
||||
} else if (cervix && !mucus) {
|
||||
setUseCervixAsSecondarySymptom(1)
|
||||
saveUseCervixAsSecondarySymptom(1)
|
||||
} else if (!cervix && !mucus) {
|
||||
setFertilityTrackingEnabled(false)
|
||||
saveFertilityTrackingEnabled(false)
|
||||
}
|
||||
setMucusTrackingCategory(mucus)
|
||||
saveMucusTrackingCategory(mucus)
|
||||
setCervixTrackingCategory(cervix)
|
||||
saveCervixTrackingCategory(cervix)
|
||||
}
|
||||
|
||||
const secondarySymptomDisabledPrompt = () => {
|
||||
if (!isFertilityTrackingEnabled) {
|
||||
Alert.alert(
|
||||
labels.secondarySymptom.disabled.title,
|
||||
labels.secondarySymptom.disabled.message
|
||||
)
|
||||
} else if (
|
||||
!isMucusTrackingCategoryEnabled == isCervixTrackingCategoryEnabled
|
||||
) {
|
||||
Alert.alert(
|
||||
labels.secondarySymptom.disabled.title,
|
||||
labels.secondarySymptom.disabled.noSecondaryEnabled
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const manageFertilityFeature =
|
||||
isTemperatureTrackingCategoryEnabled &&
|
||||
(isMucusTrackingCategoryEnabled || isCervixTrackingCategoryEnabled)
|
||||
|
||||
const cervixText = useCervixAsSecondarySymptom
|
||||
? labels.secondarySymptom.cervixModeOn
|
||||
: labels.secondarySymptom.cervixModeOff
|
||||
|
||||
const sliderDisabledPrompt = () => {
|
||||
if (!isTemperatureTrackingCategoryEnabled) {
|
||||
Alert.alert(labels.tempScale.disabled, labels.tempScale.disabledMessage)
|
||||
}
|
||||
}
|
||||
|
||||
const fertilityDisabledPrompt = () => {
|
||||
if (!manageFertilityFeature) {
|
||||
Alert.alert(
|
||||
labels.fertilityTracking.disabledTitle,
|
||||
labels.fertilityTracking.disabled
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<AppPage title={labels.customization.title}>
|
||||
<Segment title={labels.customization.trackingCategories}>
|
||||
<TrackingCategorySwitch
|
||||
onToggle={temperatureTrackingCategoryToggle}
|
||||
text={t(SYMPTOMS[1])}
|
||||
value={isTemperatureTrackingCategoryEnabled}
|
||||
symptom={SYMPTOMS[1]}
|
||||
/>
|
||||
<TrackingCategorySwitch
|
||||
onToggle={(enabled) => {
|
||||
mucusTrackingCategoryToggle(enabled)
|
||||
}}
|
||||
text={t(SYMPTOMS[2])}
|
||||
value={isMucusTrackingCategoryEnabled}
|
||||
symptom={SYMPTOMS[2]}
|
||||
/>
|
||||
<TrackingCategorySwitch
|
||||
onToggle={(enabled) => {
|
||||
cervixTrackingCategoryToggle(enabled)
|
||||
}}
|
||||
text={t(SYMPTOMS[3])}
|
||||
value={isCervixTrackingCategoryEnabled}
|
||||
symptom={SYMPTOMS[3]}
|
||||
/>
|
||||
<TrackingCategorySwitch
|
||||
onToggle={sexTrackingCategoryToggle}
|
||||
text={t(SYMPTOMS[4])}
|
||||
value={isSexTrackingCategoryEnabled}
|
||||
symptom={SYMPTOMS[4]}
|
||||
/>
|
||||
<TrackingCategorySwitch
|
||||
onToggle={desireTrackingCategoryToggle}
|
||||
text={t(SYMPTOMS[5])}
|
||||
value={isDesireTrackingCategoryEnabled}
|
||||
symptom={SYMPTOMS[5]}
|
||||
/>
|
||||
<TrackingCategorySwitch
|
||||
onToggle={painTrackingCategoryToggle}
|
||||
text={t(SYMPTOMS[6])}
|
||||
value={isPainTrackingCategoryEnabled}
|
||||
symptom={SYMPTOMS[6]}
|
||||
/>
|
||||
<TrackingCategorySwitch
|
||||
onToggle={moodTrackingCategoryToggle}
|
||||
text={t(SYMPTOMS[7])}
|
||||
value={isMoodTrackingCategoryEnabled}
|
||||
symptom={SYMPTOMS[7]}
|
||||
/>
|
||||
<TrackingCategorySwitch
|
||||
onToggle={noteTrackingCategoryToggle}
|
||||
text={t(SYMPTOMS[8])}
|
||||
value={isNoteTrackingCategoryEnabled}
|
||||
symptom={SYMPTOMS[8]}
|
||||
/>
|
||||
</Segment>
|
||||
|
||||
<Pressable onPress={fertilityDisabledPrompt}>
|
||||
<Segment title={labels.fertilityTracking.title}>
|
||||
<AppText>{labels.fertilityTracking.message}</AppText>
|
||||
<AppSwitch
|
||||
onToggle={fertilityTrackingToggle}
|
||||
text={fertilityTrackingText}
|
||||
value={isFertilityTrackingEnabled}
|
||||
disabled={!manageFertilityFeature}
|
||||
/>
|
||||
</Segment>
|
||||
</Pressable>
|
||||
|
||||
<Segment title={labels.periodPrediction.title}>
|
||||
<AppSwitch
|
||||
onToggle={onPeriodPredictionToggle}
|
||||
text={periodPredictionText}
|
||||
value={isPeriodPredictionEnabled}
|
||||
/>
|
||||
</Segment>
|
||||
|
||||
<Segment
|
||||
subheader={labels.customization.subheaderSymptoThermalMethod}
|
||||
last
|
||||
></Segment>
|
||||
|
||||
<Pressable onPress={sliderDisabledPrompt}>
|
||||
<Segment title={labels.tempScale.segmentTitle}>
|
||||
<AppText>{labels.tempScale.segmentExplainer}</AppText>
|
||||
<TemperatureSlider disabled={!isTemperatureTrackingCategoryEnabled} />
|
||||
</Segment>
|
||||
</Pressable>
|
||||
|
||||
<Pressable onPress={secondarySymptomDisabledPrompt}>
|
||||
<Segment title={labels.secondarySymptom.title}>
|
||||
<AppText>{cervixText}</AppText>
|
||||
<SelectTabGroup
|
||||
activeButton={useCervixAsSecondarySymptom}
|
||||
buttons={secondarySymptomButtons}
|
||||
onSelect={(value) => onSelectTab(value)}
|
||||
disabled={!isFertilityTrackingEnabled}
|
||||
/>
|
||||
</Segment>
|
||||
</Pressable>
|
||||
<Segment last>
|
||||
<View style={styles.line}>
|
||||
<AppIcon
|
||||
color={Colors.purple}
|
||||
name="info-with-circle"
|
||||
style={styles.icon}
|
||||
/>
|
||||
<AppText style={styles.title}>{labels.preOvu.title}</AppText>
|
||||
</View>
|
||||
<AppText>{labels.preOvu.note}</AppText>
|
||||
</Segment>
|
||||
</AppPage>
|
||||
)
|
||||
}
|
||||
|
||||
export default Settings
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
icon: {
|
||||
marginRight: Spacing.base,
|
||||
},
|
||||
line: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
title: {
|
||||
...Typography.subtitle,
|
||||
},
|
||||
})
|
||||
@@ -1,34 +0,0 @@
|
||||
import { StyleSheet } from 'react-native'
|
||||
import { Colors, Sizes } from '../../../styles'
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
paddingTop: Sizes.base,
|
||||
},
|
||||
marker: {
|
||||
backgroundColor: Colors.turquoiseDark,
|
||||
borderRadius: 50,
|
||||
elevation: 4,
|
||||
height: Sizes.subtitle,
|
||||
width: Sizes.subtitle,
|
||||
},
|
||||
slider: {
|
||||
borderRadius: 25,
|
||||
height: Sizes.small,
|
||||
paddingTop: Sizes.base,
|
||||
},
|
||||
sliderAccentBackground: {
|
||||
backgroundColor: Colors.turquoiseDark,
|
||||
},
|
||||
disabledSliderAccentBackground: {
|
||||
backgroundColor: Colors.grey,
|
||||
},
|
||||
sliderBackground: {
|
||||
backgroundColor: Colors.turquoise,
|
||||
},
|
||||
disabledSliderBackground: {
|
||||
backgroundColor: Colors.greyLight,
|
||||
},
|
||||
markerOffsetY: Sizes.tiny,
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Alert, Platform } from 'react-native'
|
||||
import { Alert } from 'react-native'
|
||||
import DocumentPicker from 'react-native-document-picker'
|
||||
import rnfs from 'react-native-fs'
|
||||
import importCsv from '../../../lib/import-export/import-from-csv'
|
||||
@@ -59,8 +59,7 @@ export default function ImportData({ resetIsDeletingData, setIsLoading }) {
|
||||
|
||||
function openImportDialog() {
|
||||
resetIsDeletingData()
|
||||
|
||||
let buttons = [
|
||||
Alert.alert(t('dialog.title'), t('dialog.message'), [
|
||||
{
|
||||
text: t('dialog.cancel'),
|
||||
style: 'cancel',
|
||||
@@ -74,13 +73,7 @@ export default function ImportData({ resetIsDeletingData, setIsLoading }) {
|
||||
text: t('dialog.delete'),
|
||||
onPress: () => startImport(true),
|
||||
},
|
||||
]
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
buttons = [buttons[0], buttons[2], buttons[1]]
|
||||
}
|
||||
|
||||
Alert.alert(t('dialog.title'), t('dialog.message'), buttons)
|
||||
])
|
||||
}
|
||||
|
||||
function showImportErrorAlert(message) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import Reminders from './reminders/reminders'
|
||||
import Customization from './customization'
|
||||
import NfpSettings from './nfp-settings'
|
||||
import DataManagement from './data-management/DataManagement'
|
||||
import Info from './Info'
|
||||
import Password from './password'
|
||||
import About from './About'
|
||||
import License from './License'
|
||||
@@ -9,9 +8,8 @@ import PrivacyPolicy from './privacy-policy'
|
||||
|
||||
export default {
|
||||
Reminders,
|
||||
Customization,
|
||||
NfpSettings,
|
||||
DataManagement,
|
||||
Info,
|
||||
Password,
|
||||
About,
|
||||
License,
|
||||
|
||||
@@ -20,15 +20,11 @@ const MenuItem = ({ item, last, navigate }) => {
|
||||
key={item.label}
|
||||
onPress={() => navigate(item.componentName)}
|
||||
>
|
||||
<View style={styles.textContainer}>
|
||||
<View>
|
||||
<AppText style={styles.title}>{t(`${item.label}.name`)}</AppText>
|
||||
{!!item.label && <AppText>{t(`${item.label}.text`)}</AppText>}
|
||||
</View>
|
||||
<AppIcon
|
||||
style={styles.chevronContainer}
|
||||
name="chevron-right"
|
||||
color={Colors.orange}
|
||||
/>
|
||||
<AppIcon name="chevron-right" color={Colors.orange} />
|
||||
</TouchableOpacity>
|
||||
</Segment>
|
||||
)
|
||||
@@ -48,13 +44,6 @@ const styles = StyleSheet.create({
|
||||
color: Colors.purple,
|
||||
fontSize: Sizes.subtitle,
|
||||
},
|
||||
textContainer: {
|
||||
flex: 5,
|
||||
},
|
||||
chevronContainer: {
|
||||
textAlign: 'right',
|
||||
flex: 1,
|
||||
},
|
||||
})
|
||||
|
||||
export default MenuItem
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Platform, StyleSheet, View } from 'react-native'
|
||||
|
||||
import AppIcon from '../../common/app-icon'
|
||||
import AppPage from '../../common/app-page'
|
||||
import AppSwitch from '../../common/app-switch'
|
||||
import AppText from '../../common/app-text'
|
||||
import TemperatureSlider from './temperature-slider'
|
||||
import Segment from '../../common/segment'
|
||||
|
||||
import { useCervixObservable, saveUseCervix } from '../../../local-storage'
|
||||
import { Colors, Spacing, Typography } from '../../../styles'
|
||||
import labels from '../../../i18n/en/settings'
|
||||
|
||||
const Settings = () => {
|
||||
const [shouldUseCervix, setShouldUseCervix] = useState(
|
||||
useCervixObservable.value
|
||||
)
|
||||
|
||||
const onCervixToggle = (value) => {
|
||||
setShouldUseCervix(value)
|
||||
saveUseCervix(value)
|
||||
}
|
||||
|
||||
const cervixText = shouldUseCervix
|
||||
? labels.useCervix.cervixModeOn
|
||||
: labels.useCervix.cervixModeOff
|
||||
|
||||
return (
|
||||
<AppPage>
|
||||
<Segment title={labels.useCervix.title}>
|
||||
<AppSwitch
|
||||
onToggle={onCervixToggle}
|
||||
text={cervixText}
|
||||
value={shouldUseCervix}
|
||||
/>
|
||||
</Segment>
|
||||
{/* for iOS disabled temporarily, TODO https://gitlab.com/bloodyhealth/drip/-/issues/545 */}
|
||||
{Platform.OS !== 'ios' && (
|
||||
<Segment title={labels.tempScale.segmentTitle}>
|
||||
<AppText>{labels.tempScale.segmentExplainer}</AppText>
|
||||
<TemperatureSlider />
|
||||
</Segment>
|
||||
)}
|
||||
<Segment last>
|
||||
<View style={styles.line}>
|
||||
<AppIcon
|
||||
color={Colors.purple}
|
||||
name="info-with-circle"
|
||||
style={styles.icon}
|
||||
/>
|
||||
<AppText style={styles.title}>{labels.preOvu.title}</AppText>
|
||||
</View>
|
||||
<AppText>{labels.preOvu.note}</AppText>
|
||||
</Segment>
|
||||
</AppPage>
|
||||
)
|
||||
}
|
||||
|
||||
export default Settings
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
icon: {
|
||||
marginRight: Spacing.base,
|
||||
},
|
||||
line: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
title: {
|
||||
...Typography.subtitle,
|
||||
},
|
||||
})
|
||||
@@ -1,16 +1,16 @@
|
||||
import React, { useState } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import PropTypes from 'prop-types'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import Slider from '@ptomasroos/react-native-multi-slider'
|
||||
|
||||
import SliderLabel from './slider-label'
|
||||
import { styles } from './slider-styles'
|
||||
import alertError from '../common/alert-error'
|
||||
import SliderLabel from './slider-label'
|
||||
|
||||
import { scaleObservable, saveTempScale } from '../../../local-storage'
|
||||
import { Colors, Sizes } from '../../../styles'
|
||||
import labels from '../../../i18n/en/settings'
|
||||
import { TEMP_MIN, TEMP_MAX, TEMP_SLIDER_STEP } from '../../../config'
|
||||
|
||||
const TemperatureSlider = ({ disabled }) => {
|
||||
const TemperatureSlider = () => {
|
||||
const savedValue = scaleObservable.value
|
||||
const [minTemperature, setMinTemperature] = useState(savedValue.min)
|
||||
const [maxTemperature, setMaxTemperature] = useState(savedValue.max)
|
||||
@@ -25,31 +25,21 @@ const TemperatureSlider = ({ disabled }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const sliderAccentBackground = disabled
|
||||
? styles.disabledSliderAccentBackground
|
||||
: styles.sliderAccentBackground
|
||||
|
||||
const sliderBackground = disabled
|
||||
? styles.disabledSliderBackground
|
||||
: styles.sliderBackground
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Slider
|
||||
customLabel={SliderLabel}
|
||||
enableLabel={true}
|
||||
markerStyle={styles.marker}
|
||||
markerOffsetY={styles.markerOffsetY}
|
||||
markerOffsetY={Sizes.tiny}
|
||||
max={TEMP_MAX}
|
||||
min={TEMP_MIN}
|
||||
onValuesChange={onTemperatureSliderChange}
|
||||
selectedStyle={styles.sliderAccentBackground}
|
||||
step={TEMP_SLIDER_STEP}
|
||||
trackStyle={styles.slider}
|
||||
unselectedStyle={styles.sliderBackground}
|
||||
values={[minTemperature, maxTemperature]}
|
||||
enabledOne={!disabled}
|
||||
enabledTwo={!disabled}
|
||||
selectedStyle={sliderAccentBackground}
|
||||
unselectedStyle={sliderBackground}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
@@ -57,6 +47,26 @@ const TemperatureSlider = ({ disabled }) => {
|
||||
|
||||
export default TemperatureSlider
|
||||
|
||||
TemperatureSlider.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
}
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
paddingTop: Sizes.base,
|
||||
},
|
||||
marker: {
|
||||
backgroundColor: Colors.turquoiseDark,
|
||||
borderRadius: 50,
|
||||
elevation: 4,
|
||||
height: Sizes.subtitle,
|
||||
width: Sizes.subtitle,
|
||||
},
|
||||
slider: {
|
||||
borderRadius: 25,
|
||||
height: Sizes.small,
|
||||
},
|
||||
sliderAccentBackground: {
|
||||
backgroundColor: Colors.turquoiseDark,
|
||||
},
|
||||
sliderBackground: {
|
||||
backgroundColor: Colors.turquoise,
|
||||
},
|
||||
})
|
||||
@@ -1,59 +0,0 @@
|
||||
import React, { useState } from 'react'
|
||||
import AppSwitch from '../../common/app-switch'
|
||||
import AdvanceNoticeDaysSlider from '../customization/advance-notice-days-slider'
|
||||
|
||||
import {
|
||||
periodReminderObservable,
|
||||
savePeriodReminder,
|
||||
periodPredictionObservable,
|
||||
saveAdvanceNoticeDays,
|
||||
advanceNoticeDaysObservable,
|
||||
} from '../../../local-storage'
|
||||
import labels from '../../../i18n/en/settings'
|
||||
|
||||
const PeriodReminder = () => {
|
||||
const isPeriodPredictionDisabled = !periodPredictionObservable.value
|
||||
|
||||
const [isPeriodReminderEnabled, setIsPeriodReminderEnabled] = useState(
|
||||
periodReminderObservable.value.enabled
|
||||
)
|
||||
|
||||
const [advanceNoticeDays, setAdvanceNoticeDays] = useState(
|
||||
advanceNoticeDaysObservable.value
|
||||
)
|
||||
|
||||
const periodReminderToggle = (isEnabled) => {
|
||||
setIsPeriodReminderEnabled(isEnabled)
|
||||
savePeriodReminder({ enabled: isEnabled })
|
||||
}
|
||||
|
||||
const handleAdvanceNoticeDaysChange = (days) => {
|
||||
setAdvanceNoticeDays(days)
|
||||
saveAdvanceNoticeDays(days)
|
||||
}
|
||||
|
||||
const reminderText =
|
||||
advanceNoticeDays == 1
|
||||
? labels.periodReminder.reminderTextSingular
|
||||
: labels.periodReminder.reminderTextPlural(advanceNoticeDays)
|
||||
|
||||
return (
|
||||
<>
|
||||
<AppSwitch
|
||||
onToggle={periodReminderToggle}
|
||||
text={reminderText}
|
||||
value={isPeriodReminderEnabled}
|
||||
disabled={isPeriodPredictionDisabled}
|
||||
/>
|
||||
{isPeriodReminderEnabled && (
|
||||
<AdvanceNoticeDaysSlider
|
||||
disabled={isPeriodPredictionDisabled}
|
||||
advanceNoticeDays={parseInt(advanceNoticeDays)}
|
||||
onAdvanceNoticeDaysChange={handleAdvanceNoticeDaysChange}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default PeriodReminder
|
||||
@@ -1,49 +1,38 @@
|
||||
import React from 'react'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import AppPage from '../../common/app-page'
|
||||
import AppSwitch from '../../common/app-switch'
|
||||
import Segment from '../../common/segment'
|
||||
import TemperatureReminder from './temperature-reminder'
|
||||
import PeriodReminder from './period-reminder'
|
||||
|
||||
import {
|
||||
periodPredictionObservable,
|
||||
temperatureTrackingCategoryObservable,
|
||||
periodReminderObservable,
|
||||
savePeriodReminder,
|
||||
} from '../../../local-storage'
|
||||
|
||||
import labels from '../../../i18n/en/settings'
|
||||
import { Alert, Pressable } from 'react-native'
|
||||
|
||||
const Reminders = () => {
|
||||
const periodReminderDisabledPrompt = () => {
|
||||
if (!periodPredictionObservable.value) {
|
||||
Alert.alert(
|
||||
labels.periodReminder.alertNoPeriodReminder.title,
|
||||
labels.periodReminder.alertNoPeriodReminder.message
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const tempReminderDisabledPrompt = () => {
|
||||
if (!temperatureTrackingCategoryObservable.value) {
|
||||
Alert.alert(
|
||||
labels.tempReminder.alertNoTempReminder.title,
|
||||
labels.tempReminder.alertNoTempReminder.message
|
||||
)
|
||||
}
|
||||
const [isPeriodReminderEnabled, setIsPeriodReminderEnabled] = useState(
|
||||
periodReminderObservable.value.enabled
|
||||
)
|
||||
const periodReminderToggle = (isEnabled) => {
|
||||
setIsPeriodReminderEnabled(isEnabled)
|
||||
savePeriodReminder({ enabled: isEnabled })
|
||||
}
|
||||
|
||||
return (
|
||||
<AppPage>
|
||||
<Pressable onPress={periodReminderDisabledPrompt}>
|
||||
<Segment title={labels.periodReminder.title}>
|
||||
<PeriodReminder />
|
||||
</Segment>
|
||||
</Pressable>
|
||||
<Pressable onPress={tempReminderDisabledPrompt}>
|
||||
<Segment title={labels.tempReminder.title} last>
|
||||
<TemperatureReminder />
|
||||
</Segment>
|
||||
</Pressable>
|
||||
<Segment title={labels.tempReminder.title}>
|
||||
<TemperatureReminder />
|
||||
</Segment>
|
||||
<Segment title={labels.periodReminder.title} last>
|
||||
<AppSwitch
|
||||
onToggle={periodReminderToggle}
|
||||
text={labels.periodReminder.reminderText}
|
||||
value={isPeriodReminderEnabled}
|
||||
/>
|
||||
</Segment>
|
||||
</AppPage>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import AppSwitch from '../../common/app-switch'
|
||||
import {
|
||||
saveTempReminder,
|
||||
tempReminderObservable,
|
||||
temperatureTrackingCategoryObservable,
|
||||
} from '../../../local-storage'
|
||||
import padWithZeros from '../../helpers/pad-time-with-zeros'
|
||||
|
||||
@@ -52,7 +51,6 @@ const TemperatureReminder = () => {
|
||||
onToggle={temperatureReminderToggle}
|
||||
text={tempReminderText}
|
||||
value={isEnabled}
|
||||
disabled={!temperatureTrackingCategoryObservable.value}
|
||||
/>
|
||||
<DateTimePicker
|
||||
isVisible={isTimePickerVisible}
|
||||
|
||||
@@ -7,8 +7,8 @@ import MenuItem from './menu-item'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const menuItems = [
|
||||
{ label: 'customization', componentName: 'Customization' },
|
||||
{ label: 'reminders', componentName: 'Reminders' },
|
||||
{ label: 'nfpSettings', componentName: 'NfpSettings' },
|
||||
{ label: 'dataManagement', componentName: 'DataManagement' },
|
||||
{ label: 'password', componentName: 'Password' },
|
||||
]
|
||||
|
||||
@@ -3,7 +3,7 @@ import { StyleSheet, View } from 'react-native'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import AppText from '../common/app-text'
|
||||
import { formatDecimal } from '../helpers/cycle-day'
|
||||
|
||||
import { Sizes, Spacing, Typography } from '../../styles'
|
||||
|
||||
const StatsOverview = ({ data }) => {
|
||||
@@ -16,9 +16,7 @@ StatsOverview.propTypes = {
|
||||
|
||||
const Row = ({ rowContent }) => {
|
||||
const isStandardDeviation = rowContent[1].includes('deviation')
|
||||
if (isStandardDeviation && rowContent[0] !== '—') {
|
||||
rowContent[0] = formatDecimal(rowContent[0], 1)
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.row}>
|
||||
<Cell content={rowContent[0]} isLeft />
|
||||
|
||||
@@ -11,7 +11,6 @@ import PeriodDetailsModal from './PeriodDetailsModal'
|
||||
|
||||
import cycleModule from '../../lib/cycle'
|
||||
import { getCycleLengthStats as getCycleInfo } from '../../lib/cycle-length'
|
||||
import { formatDecimal } from '../helpers/cycle-day'
|
||||
|
||||
import { Containers, Sizes, Spacing, Typography } from '../../styles'
|
||||
|
||||
@@ -28,7 +27,6 @@ const Stats = () => {
|
||||
numberOfCycles > 0
|
||||
? getCycleInfo(cycleLengths)
|
||||
: { minimum: '—', maximum: '—', stdDeviation: '—' }
|
||||
|
||||
const standardDeviation = cycleData.stdDeviation
|
||||
? cycleData.stdDeviation
|
||||
: '—'
|
||||
@@ -39,10 +37,6 @@ const Stats = () => {
|
||||
[numberOfCycles, t('overview.completedCycles')],
|
||||
]
|
||||
|
||||
if (cycleData.mean) {
|
||||
cycleData.mean = formatDecimal(cycleData.mean, 1)
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.pageContainer}>
|
||||
<ScrollView contentContainerStyle={styles.overviewContainer}>
|
||||
|
||||
@@ -15,13 +15,12 @@ export const SYMPTOMS = [
|
||||
|
||||
export const CHART_COLUMN_WIDTH = 32
|
||||
export const CHART_COLUMN_MIDDLE = CHART_COLUMN_WIDTH / 2
|
||||
export const CHART_DOT_RADIUS_SYMPTOM = scale(6)
|
||||
export const CHART_DOT_RADIUS_TEMPERATURE = scale(4)
|
||||
export const CHART_DOT_RADIUS = scale(6)
|
||||
export const CHART_GRID_LINE_HORIZONTAL_WIDTH =
|
||||
PixelRatio.roundToNearestPixel(0.3)
|
||||
export const CHART_ICON_SIZE = scale(20)
|
||||
export const CHART_STROKE_WIDTH = scale(1.5)
|
||||
export const CHART_SYMPTOM_HEIGHT_RATIO = scale(0.06)
|
||||
export const CHART_STROKE_WIDTH = scale(3)
|
||||
export const CHART_SYMPTOM_HEIGHT_RATIO = scale(0.08)
|
||||
export const CHART_XAXIS_HEIGHT_RATIO = scale(0.1)
|
||||
export const CHART_YAXIS_WIDTH = scale(32)
|
||||
export const CHART_TICK_WIDTH = scale(44)
|
||||
@@ -33,10 +32,6 @@ export const TEMP_MAX = 39
|
||||
export const TEMP_MIN = 35
|
||||
export const TEMP_SLIDER_STEP = 0.5
|
||||
|
||||
export const ADVANCE_PERIOD_NOTICE_DAYS_MIN = 1
|
||||
export const ADVANCE_PERIOD_NOTICE_DAYS_MAX = 7
|
||||
export const ADVANCE_PERIOD_NOTICE_DAYS_INIT_VALUE = 3
|
||||
|
||||
export const HIT_SLOP = {
|
||||
top: verticalScale(20),
|
||||
bottom: verticalScale(20),
|
||||
|
||||
@@ -7,16 +7,18 @@
|
||||
"chart": {
|
||||
"tutorial": "You can swipe the chart to view more dates."
|
||||
},
|
||||
"symptoms": {
|
||||
"bleeding": "bleeding",
|
||||
"temperature": "temperature",
|
||||
"mucus": "cervical mucus",
|
||||
"cervix": "cervix",
|
||||
"note": "note",
|
||||
"desire": "desire",
|
||||
"sex": "sex",
|
||||
"pain": "pain",
|
||||
"mood": "mood"
|
||||
"cycleDay": {
|
||||
"symptomBox": {
|
||||
"bleeding": "Bleeding",
|
||||
"temperature": "Temperature",
|
||||
"mucus": "Cervical Mucus",
|
||||
"cervix": "Cervix",
|
||||
"note": "Note",
|
||||
"desire": "Desire",
|
||||
"sex": "Sex",
|
||||
"pain": "Pain",
|
||||
"mood": "Mood"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"bleedingPrediction": {
|
||||
@@ -45,13 +47,11 @@
|
||||
"text": "The drips are developing this app on a volunteer basis. We are always grateful for support. This could mean condriputing to the code, giving feedback, suggesting improvements or features, testing or donating. It helps and motivates us maintaining this app and developing new features. Thank you for your support!"
|
||||
},
|
||||
"intro": {
|
||||
"text": "Please note that your data is stored locally on your phone and not on a server. This means your data cannot be read by anyone else unless they have access to your phone. We want to ensure that you stay in control of your own data. If you are planning to switch or reset your phone, please remember to export your data before doing so. You can reinstall the app afterwards and import your data.\n\nIf you encounter any issues, please take a look at our Frequently Asked Questions page.",
|
||||
"faq": "FAQ",
|
||||
"contact": "\nIf your issue is not listed, don't hesitate to contact us via email. You can also contribute to the code base on Gitlab and visit our website."
|
||||
"text": "Please note that your data is stored locally on your phone and not on a server. This means your data cannot be read by anyone else unless they have access to your phone. We want to ensure that you stay in control of your own data. If you are planning to switch or reset your phone, please remember to export your data before doing so. You can reinstall the app afterwards and import your data.\n\nIf you encounter any technical issues, don't hesitate to contact us via email. You can also contribute to the code base on Gitlab and visit our website."
|
||||
},
|
||||
"philosophy": {
|
||||
"title": "Remember to think for yourself",
|
||||
"text": "drip. makes period predictions for you and helps you apply the sympto-thermal method for fertility awareness. But please remember that this app is made by humans, and humans make mistakes. Always think for yourself: \"Does this make sense?\" Remember, you don't need an app to understand your cycle! However, drip. wants to support you and make period tracking easier, more transparent and secure."
|
||||
"text": "drip. makes period predictions for you and helps you apply NFP fertility awareness rules. But please remember that this app is made by humans, and humans make mistakes. Always think for yourself: \"Does this make sense?\" Remember, you don't need an app to understand your cycle! However, drip. wants to support you and make period tracking easier, more transparent and secure."
|
||||
},
|
||||
"title": "About",
|
||||
"version": {
|
||||
@@ -114,29 +114,22 @@
|
||||
"menuItem": {
|
||||
"dataManagement": {
|
||||
"name": "Data",
|
||||
"text": "Import, export or delete your data"
|
||||
"text": "import, export or delete your data"
|
||||
},
|
||||
"customization": {
|
||||
"name": "Customization",
|
||||
"text": "Define how you want to use drip"
|
||||
"nfpSettings": {
|
||||
"name": "NFP settings",
|
||||
"text": "define how you want to use NFP"
|
||||
},
|
||||
"password": {
|
||||
"name": "Password",
|
||||
"text": "Set, edit or delete your password"
|
||||
"text": ""
|
||||
},
|
||||
"reminders": {
|
||||
"name": "Reminders",
|
||||
"text": "Turn on/off reminders"
|
||||
},
|
||||
"info": {
|
||||
"name": "Info",
|
||||
"text": "Learn more about how drip works"
|
||||
"text": "turn on/off reminders"
|
||||
}
|
||||
},
|
||||
"title": "Settings"
|
||||
},
|
||||
"info": {
|
||||
"title": "info"
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
|
||||
@@ -4,71 +4,70 @@ export const intensity = ['low', 'medium', 'high']
|
||||
export const bleeding = {
|
||||
labels: ['spotting', 'light', 'medium', 'heavy'],
|
||||
heaviness: {
|
||||
header: 'Heaviness',
|
||||
explainer: 'How heavy is the bleeding?',
|
||||
header: "Heaviness",
|
||||
explainer: "How heavy is the bleeding?",
|
||||
},
|
||||
exclude: {
|
||||
header: 'Exclude',
|
||||
explainer: "You can exclude this value if it's not menstrual bleeding",
|
||||
},
|
||||
header: "Exclude",
|
||||
explainer: "You can exclude this value if it's not menstrual bleeding"
|
||||
}
|
||||
}
|
||||
|
||||
export const cervix = {
|
||||
subcategories: {
|
||||
opening: 'opening',
|
||||
firmness: 'firmness',
|
||||
position: 'position',
|
||||
position: 'position'
|
||||
},
|
||||
opening: {
|
||||
categories: ['closed', 'medium', 'open'],
|
||||
explainer: 'Is your cervix open or closed?',
|
||||
explainer: 'Is your cervix open or closed?'
|
||||
},
|
||||
firmness: {
|
||||
categories: ['hard', 'soft'],
|
||||
explainer: "When it's hard, it might feel like the tip of your nose",
|
||||
explainer: "When it's hard, it might feel like the tip of your nose"
|
||||
},
|
||||
position: {
|
||||
categories: ['low', 'medium', 'high'],
|
||||
explainer: 'How high up in the vagina is the cervix?',
|
||||
explainer: 'How high up in the vagina is the cervix?'
|
||||
},
|
||||
excludeExplainer:
|
||||
"You can exclude this value if you don't want to use it for fertility detection.",
|
||||
excludeExplainer: "You can exclude this value if you don't want to use it for fertility detection.",
|
||||
actionHint: 'Choose values for at least "Opening" and "Firmness" to save.'
|
||||
}
|
||||
|
||||
export const mucus = {
|
||||
subcategories: {
|
||||
feeling: 'feeling',
|
||||
texture: 'texture',
|
||||
texture: 'texture'
|
||||
},
|
||||
feeling: {
|
||||
categories: ['dry', 'nothing', 'wet', 'slippery'],
|
||||
explainer: 'What does your vaginal entrance feel like?',
|
||||
explainer: 'What does your vaginal entrance feel like?'
|
||||
},
|
||||
texture: {
|
||||
categories: ['nothing', 'creamy', 'egg white'],
|
||||
explainer:
|
||||
'Looking at and touching your cervical mucus, which describes it best?',
|
||||
explainer: "Looking at and touching your cervical mucus, which describes it best?"
|
||||
},
|
||||
excludeExplainer:
|
||||
"You can exclude this value if you don't want to use it for fertility detection",
|
||||
excludeExplainer: "You can exclude this value if you don't want to use it for fertility detection",
|
||||
actionHint: 'Choose values for both "Feeling" and "Texture" to save.'
|
||||
}
|
||||
|
||||
export const desire = {
|
||||
header: 'Intensity',
|
||||
explainer: 'How would you rate your sexual desire?',
|
||||
explainer: 'How would you rate your sexual desire?'
|
||||
}
|
||||
|
||||
export const sex = {
|
||||
categories: {
|
||||
categories:{
|
||||
solo: 'solo',
|
||||
partner: 'partner',
|
||||
},
|
||||
header: 'Activity',
|
||||
header: "Activity",
|
||||
explainer: 'Were you sexually active today?',
|
||||
}
|
||||
|
||||
export const contraceptives = {
|
||||
categories: {
|
||||
categories:{
|
||||
condom: 'condom',
|
||||
pill: 'pill',
|
||||
iud: 'iud',
|
||||
@@ -79,8 +78,8 @@ export const contraceptives = {
|
||||
none: 'none',
|
||||
other: 'other',
|
||||
},
|
||||
header: 'Contraceptives',
|
||||
explainer: 'Did you use contraceptives?',
|
||||
header: "Contraceptives",
|
||||
explainer: 'Did you use contraceptives?'
|
||||
}
|
||||
|
||||
export const pain = {
|
||||
@@ -92,9 +91,9 @@ export const pain = {
|
||||
nausea: 'nausea',
|
||||
tenderBreasts: 'tender breasts',
|
||||
migraine: 'migraine',
|
||||
other: 'other',
|
||||
other: 'other'
|
||||
},
|
||||
explainer: 'How did your body feel today?',
|
||||
explainer: 'How did your body feel today?'
|
||||
}
|
||||
|
||||
export const mood = {
|
||||
@@ -108,39 +107,37 @@ export const mood = {
|
||||
energetic: 'energetic',
|
||||
fatigue: 'fatigue',
|
||||
angry: 'angry',
|
||||
other: 'other',
|
||||
other: 'other'
|
||||
},
|
||||
explainer: 'How did you feel today?',
|
||||
explainer: 'How did you feel today?'
|
||||
}
|
||||
|
||||
export const temperature = {
|
||||
outOfRangeWarning:
|
||||
'This temperature value is out of the current range for the temperature chart. You can change the range in the settings.',
|
||||
outOfAbsoluteRangeWarning:
|
||||
'This temperature value is too high or low to be shown on the temperature chart.',
|
||||
// disabled temporarily, TODO https://gitlab.com/bloodyhealth/drip/-/issues/545 */}
|
||||
// outOfRangeWarning: 'This temperature value is out of the current range for the temperature chart. You can change the range in the settings.',
|
||||
outOfRangeWarning: 'This temperature value is too high or low to be shown on the temperature chart.',
|
||||
outOfAbsoluteRangeWarning: 'This temperature value is too high or low to be shown on the temperature chart.',
|
||||
saveAnyway: 'Save anyway',
|
||||
temperature: {
|
||||
header: 'Temperature',
|
||||
explainer:
|
||||
'Take your temperature right after waking up, before getting out of bed',
|
||||
header: "Temperature",
|
||||
explainer: 'Take your temperature right after waking up, before getting out of bed'
|
||||
},
|
||||
time: 'Time',
|
||||
time: "Time",
|
||||
note: {
|
||||
header: 'Note',
|
||||
explainer:
|
||||
'Is there anything that could have influenced this value, such as bad sleep or alcohol consumption?',
|
||||
header: "Note",
|
||||
explainer: 'Is there anything that could have influenced this value, such as bad sleep or alcohol consumption?'
|
||||
},
|
||||
exclude: {
|
||||
header: 'Exclude',
|
||||
explainer:
|
||||
"You can exclude this value if you don't want to use it for fertility detection",
|
||||
},
|
||||
header: "Exclude",
|
||||
explainer: "You can exclude this value if you don't want to use it for fertility detection"
|
||||
}
|
||||
}
|
||||
|
||||
export const noteExplainer = 'Anything you want to add for the day?'
|
||||
export const noteExplainer = "Anything you want to add for the day?"
|
||||
|
||||
export const general = {
|
||||
cycleDayNumber: 'Cycle day ',
|
||||
today: 'Today',
|
||||
cycleDayNumber: "Cycle day ",
|
||||
today: "Today"
|
||||
}
|
||||
|
||||
export const sharedDialogs = {
|
||||
@@ -150,5 +147,5 @@ export const sharedDialogs = {
|
||||
reallyDeleteData: 'Yes, I am sure',
|
||||
save: 'Save',
|
||||
delete: 'Delete',
|
||||
disabledInfo: 'There is some data missing',
|
||||
disabledInfo: 'There is some data missing'
|
||||
}
|
||||
|
||||
@@ -70,14 +70,14 @@ export const fertilityStatus = {
|
||||
unknown:
|
||||
'We cannot show any cycle information because no period data has been added.',
|
||||
preOvuText:
|
||||
"According to the sympto-thermal method, you may assume 5 days of infertility at the beginning of your cycle, provided you don't observe any fertile cervical mucus or cervix values.",
|
||||
"With NFP rules, you may assume 5 days of infertility at the beginning of your cycle, provided you don't observe any fertile cervical mucus or cervix values.",
|
||||
periOvuText:
|
||||
'We were not able to detect both a temperature shift and cervical mucus or cervix shift.',
|
||||
periOvuUntilEveningText: (tempRule) => {
|
||||
return (
|
||||
'We detected a temperature shift (' +
|
||||
['regular', '1st exception', '2nd exception'][tempRule] +
|
||||
' temperature rule), as well as a cervical mucus/cervix shift according to the sympto-thermal method. In the evening today you may assume infertility, but ' +
|
||||
' temperature rule), as well as a cervical mucus/cervix shift according to NFP rules. In the evening today you may assume infertility, but ' +
|
||||
'always remember to double-check for yourself. Make sure the data makes sense to you.'
|
||||
)
|
||||
},
|
||||
@@ -85,7 +85,7 @@ export const fertilityStatus = {
|
||||
return (
|
||||
'We detected a temperature shift (' +
|
||||
['regular', '1st exception', '2nd exception'][tempRule] +
|
||||
' temperature rule), as well as a cervical mucus/cervix shift according to the sympto-thermal method. You may assume infertility, but always remember to ' +
|
||||
' temperature rule), as well as a cervical mucus/cervix shift according to NFP rules. You may assume infertility, but always remember to ' +
|
||||
'double-check for yourself. Make sure the data makes sense to you.'
|
||||
)
|
||||
},
|
||||
|
||||
@@ -39,8 +39,4 @@ export default {
|
||||
url: 'https://www.flaticon.com',
|
||||
text: 'Flaticon',
|
||||
},
|
||||
faq: {
|
||||
url: 'https://dripapp.org/faq',
|
||||
text: 'FAQ',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import links from './links'
|
||||
|
||||
export default {
|
||||
customization: {
|
||||
title: 'Customization',
|
||||
trackingCategories: 'Tracking categories',
|
||||
subheaderSymptoThermalMethod: 'Sympto-thermal method settings',
|
||||
},
|
||||
export: {
|
||||
errors: {
|
||||
noData: 'There is no data to export',
|
||||
@@ -37,71 +32,31 @@ export default {
|
||||
tempScale: {
|
||||
segmentTitle: 'Temperature scale',
|
||||
segmentExplainer:
|
||||
'Change the minimum and maximum value for the temperature chart.',
|
||||
'Change the minimum and maximum value for the temperature chart',
|
||||
min: 'Min',
|
||||
max: 'Max',
|
||||
loadError: 'Could not load saved temperature scale settings',
|
||||
saveError: 'Could not save temperature scale settings',
|
||||
disabled: 'Disabled',
|
||||
disabledMessage:
|
||||
'To use the temperature scale please first enable temperature tracking above.',
|
||||
},
|
||||
|
||||
tempReminder: {
|
||||
title: 'Temperature reminder',
|
||||
noTimeSet: 'Set a time for a daily reminder to take your temperature',
|
||||
timeSet: (time) => `Daily reminder set for ${time}`,
|
||||
notification: 'Record your morning temperature',
|
||||
alertNoTempReminder: {
|
||||
title: 'Temperature turned off',
|
||||
message:
|
||||
'To use the temperature reminder please first enable the temperature tracking category in the customization settings.',
|
||||
},
|
||||
},
|
||||
periodReminder: {
|
||||
title: 'Next period reminder',
|
||||
reminderTextSingular:
|
||||
'Get a notification 1 day before your next period is likely to start.',
|
||||
reminderTextPlural: (days) =>
|
||||
`Get a notification ${days} days before your next period is likely to start.`,
|
||||
notification: (advanceNoticeDays, daysToEndOfPrediction) =>
|
||||
`Your next period is likely to start in ${advanceNoticeDays} to ${daysToEndOfPrediction} days.`,
|
||||
alertNoPeriodReminder: {
|
||||
title: 'Period predictions turned off',
|
||||
message:
|
||||
'To use the period reminder please first enable period predictions in the customization settings.',
|
||||
},
|
||||
reminderText:
|
||||
'Get a notification 3 days before your next period is likely to start.',
|
||||
notification: (daysToEndOfPrediction) =>
|
||||
`Your next period is likely to start in 3 to ${daysToEndOfPrediction} days.`,
|
||||
},
|
||||
fertilityTracking: {
|
||||
title: 'Fertility phases calculation',
|
||||
disabledTitle: 'Disabled',
|
||||
disabled:
|
||||
'To use fertility phases calculation please enable both temperature tracking and either cervical mucus or cervix tracking above.',
|
||||
message:
|
||||
'If you enter menstrual bleeding, temperature and cervical mucus or cervix data according to the sympto-thermal method, drip will calculate cycle phases with the provided data.',
|
||||
on: 'If you switch this off, drip will not show fertility related information.',
|
||||
off: 'If you switch this on, drip will show fertility related information.',
|
||||
},
|
||||
secondarySymptom: {
|
||||
useCervix: {
|
||||
title: 'Secondary symptom',
|
||||
cervixModeOn:
|
||||
'Cervix values are being used for fertility detection according to the sympto-thermal method.',
|
||||
'Cervix values are being used for symptothermal fertility detection. You can switch here to use cervical mucus values for symptothermal fertility detection',
|
||||
cervixModeOff:
|
||||
'Cervical mucus values are being used for fertility detection according to the sympto-thermal method.',
|
||||
disabled: {
|
||||
title: 'Disabled',
|
||||
message:
|
||||
'To set a secondary symptom please first enable the cervical mucus or cervix tracking category as well as temperature and fertility phases calculation above.',
|
||||
noSecondaryEnabled:
|
||||
'To switch the secondary symptom both cervical mucus and cervix need to be enabled above.',
|
||||
},
|
||||
mucus: 'cervical mucus',
|
||||
cervix: 'cervix',
|
||||
},
|
||||
periodPrediction: {
|
||||
title: 'Period predictions',
|
||||
on: 'drip predicts your 3 next menstrual bleedings based on statistics if you previously tracked at least 3 complete cycles.',
|
||||
off: 'There are no predictions for menstrual cycles displayed. If turned on, the calendar and the home screen will display period predictions.',
|
||||
'By default, cervical mucus values are being used for symptothermal fertility detection. You can switch here to use cervix values for symptothermal fertility detection',
|
||||
},
|
||||
passwordSettings: {
|
||||
title: 'App password',
|
||||
@@ -144,6 +99,6 @@ Making any changes to your password setting will keep your data as it was before
|
||||
},
|
||||
preOvu: {
|
||||
title: 'Infertile days at cycle start',
|
||||
note: `drip. applies the sympto-thermal method for calculating infertile days at the start of the cycle (see ${links.wiki.url} for more info). However, drip. does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths in case no past sympto-thermal info is available.`,
|
||||
note: `drip. applies NFP's rules for calculating infertile days at the start of the cycle (see ${links.wiki.url} for more info). However, drip. does not currently apply the so called 20-day-rule, which determines infertile days at the cycle start from past cycle lengths in case no past symptothermal info is available.`,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export const generalInfo = {
|
||||
3. and menstrual bleeding
|
||||
the app helps you identify in which phase of the menstrual cycle you are.
|
||||
|
||||
drip. makes period predictions for you and helps you apply the sympto-thermal method for fertility awareness. But please remember that this app is made by humans, and humans make mistakes. Always think for yourself: "Does this make sense?" Remember, you don't need an app to understand your cycle! However, drip. wants to support you and make period tracking easier, more transparent and secure.
|
||||
drip. makes period predictions for you and helps you apply NFP fertility awareness rules. But please remember that this app is made by humans, and humans make mistakes. Always think for yourself: "Does this make sense?" Remember, you don't need an app to understand your cycle! However, drip. wants to support you and make period tracking easier, more transparent and secure.
|
||||
|
||||
Please find more info on the sympto-thermal method in ${links.wiki.url}.`,
|
||||
noNfpSymptom: `The app allows you to track this symptom for your information, it is not taken into account for any calculation. On the chart you can check how often you track this symptom.`,
|
||||
@@ -25,9 +25,9 @@ export default {
|
||||
After tracking at least 3 menstrual cycles, drip. will give you an overview of
|
||||
· how long your cycles last on average (in "stats"),
|
||||
· whether the length of your cycles varied significantly (in "stats" and in bleeding predictions)
|
||||
· and predict your next 3 cycles with a range of 3 or 5 days (on home screen and "calendar") if this functionality is enabled in the customization settings.
|
||||
· and predict your next 3 cycles with a range of 3 or 5 days (on home screen and "calendar").
|
||||
|
||||
The app allows you to track different intensities of bleeding. On the chart and on the calendar, bleeding values are colored in different shades of red. The darker, the more intense your bleeding. Every bleeding value that is not excluded is taken into account for fertility calculation and period predictions.
|
||||
The app allows you to track different intensities of bleeding. On the chart and on the calendar, bleeding values are colored in different shades of red. The darker, the more intense your bleeding. Every bleeding value that is not excluded is taken into account for fertility calculation and prediction for the start of next cycles.
|
||||
|
||||
Excluding bleeding values is for tracking bleeding when it's not marking the start of a new cycle or the continuation of menstrual bleeding the day(s) before, e.g. bleeding caused by ovulation or a miscarriage.
|
||||
|
||||
@@ -39,7 +39,7 @@ ${generalInfo.nfpTfyReminder}`,
|
||||
|
||||
Tracking how open or closed and how firm or soft the cervix feels can help determine in which phase of the menstrual cycle you are.
|
||||
|
||||
By default, the secondary symptom the app uses for the sympto-thermal method is cervical mucus, but you can change it to cervix in "Settings" -> "Customization".
|
||||
By default, the secondary symptom the app uses for NFP evaluation is cervical mucus, but you can change it to cervix in "Settings" -> "NFP Settings".
|
||||
|
||||
· How to identify a fertile cervix?
|
||||
A fertile cervix is open and feels soft like your earlobes. In contrast, an infertile cervix feels closed and hard, like the tip of your nose. If the cervix feels anything other than closed and hard, drip. takes it as a sign of fertility. On the chart, a fertile cervix is colored in dark yellow, and infertile cervix is colored in light yellow.
|
||||
@@ -74,10 +74,10 @@ ${generalInfo.curiousNfp}`,
|
||||
title: 'Tracking cervical mucus',
|
||||
text: `Cervical mucus can help determine in which phase of the menstrual cycle you are.
|
||||
|
||||
By default the secondary symptom the app uses for the sympto-thermal method is cervical mucus. You can change this in the customization settings.
|
||||
By default the secondary symptom the app uses for NFP evaluation is cervical mucus.
|
||||
|
||||
· How to identify fertile cervical mucus?
|
||||
Tracking the feeling and the texture of your cervical mucus on a daily basis helps you identify changes of the quality of the cervical mucus. The values you enter for both feeling and texture of your cervical mucus are combined by drip. into one of five values following the sympto-thermal method.
|
||||
Tracking the feeling and the texture of your cervical mucus on a daily basis helps you identify changes of the quality of the cervical mucus. The values you enter for both feeling and texture of your cervical mucus are combined by drip. into one of five NFP-conforming values.
|
||||
From lowest to best quality:
|
||||
· t = (dry feeling + no texture),
|
||||
· ∅ = (no feeling + no texture),
|
||||
@@ -87,7 +87,7 @@ From lowest to best quality:
|
||||
|
||||
On the chart, cervical mucus is colored in blue: the darker the shade of blue the better the quality of your cervical mucus.
|
||||
|
||||
Please note that drip. does not yet support "parenthesis values": According to the sympto-thermal method, you can qualify a cervical mucus value by putting parentheses around it, to indicate that it doesn't fully meet the descriptors of one of the five categories, and instead is in between. This functionality will be supported in the future.
|
||||
Please note that drip. does not yet support "parenthesis values": According to NFP rules, you can qualify a cervical mucus value by putting parentheses around it, to indicate that it doesn't fully meet the descriptors of one of the five categories, and instead is in between. This functionality will be supported in the future.
|
||||
|
||||
${generalInfo.chartNfp}
|
||||
|
||||
@@ -125,7 +125,7 @@ ${generalInfo.curiousNfp}`,
|
||||
title: 'Tracking body basal temperature',
|
||||
text: `One of the body signs you need to track for knowing your fertility status is your body basal temperature. The body temperature changes over the course of a menstrual cycle, it rises after ovulation.
|
||||
|
||||
By default the secondary symptom is cervical mucus, but you can change it to cervix in "Settings" -> "Customization".
|
||||
By default the secondary symptom is cervical mucus, but you can change it to cervix in "Settings" -> "NFP Settings".
|
||||
|
||||
· What is body basal temperature?
|
||||
It's your temperature after lying still for at least 6 hours. For many, this is when they are waking up in the morning after sleeping at least 6 hours and before getting up.
|
||||
|
||||
@@ -2,35 +2,23 @@ require_relative '../node_modules/react-native/scripts/react_native_pods'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
platform :ios, '11.0'
|
||||
install! 'cocoapods', :deterministic_uuids => false
|
||||
|
||||
target 'drip' do
|
||||
config = use_native_modules!
|
||||
|
||||
# Flags change depending on the env values.
|
||||
flags = get_default_flags()
|
||||
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
# to enable hermes on iOS, change `false` to `true` and then install pods
|
||||
:hermes_enabled => flags[:hermes_enabled],
|
||||
:fabric_enabled => flags[:fabric_enabled],
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
:hermes_enabled => false
|
||||
)
|
||||
|
||||
target 'dripTests' do
|
||||
inherit! :complete
|
||||
# Pods for testing
|
||||
end
|
||||
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable the next line.
|
||||
use_flipper!()
|
||||
|
||||
|
||||
post_install do |installer|
|
||||
react_native_post_install(installer)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 54;
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00E356F31AD99517003FC87E /* dripTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* dripTests.m */; };
|
||||
0C80B921A6F3F58F76C31292 /* libPods-drip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-drip.a */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
540918B325AB726000086AE1 /* OpenSans-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 540918A325AB725F00086AE1 /* OpenSans-Light.ttf */; };
|
||||
@@ -31,16 +30,17 @@
|
||||
5472A45A25BB7807005E81DE /* drip-icon-font.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 5472A44925BB7806005E81DE /* drip-icon-font.ttf */; };
|
||||
5472A45B25BB7807005E81DE /* drip-icon-font.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 5472A44925BB7806005E81DE /* drip-icon-font.ttf */; };
|
||||
5472A45E25BB7C43005E81DE /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 5472A45C25BB7C42005E81DE /* Entypo.ttf */; };
|
||||
5488D8D728ABF478008DD66D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5488D8D628ABF478008DD66D /* LaunchScreen.storyboard */; };
|
||||
54DFE73A25D94D6E0025C3FC /* swipe.png in Resources */ = {isa = PBXBuildFile; fileRef = 54DFE73925D94D6E0025C3FC /* swipe.png */; };
|
||||
54DFE73B25D94D6E0025C3FC /* swipe.png in Resources */ = {isa = PBXBuildFile; fileRef = 54DFE73925D94D6E0025C3FC /* swipe.png */; };
|
||||
54DFE73D25D94DED0025C3FC /* cycle-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 54DFE73C25D94DED0025C3FC /* cycle-icon.png */; };
|
||||
54DFE73E25D94DED0025C3FC /* cycle-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 54DFE73C25D94DED0025C3FC /* cycle-icon.png */; };
|
||||
54E1D49923E7588F003FA37B /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
|
||||
54E1D49923E7588F003FA37B /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54E1D49823E7588F003FA37B /* JavaScriptCore.framework */; };
|
||||
62F2A4645AC84CDC9506FF27 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AEBF0735214455AAEDF56D5 /* libc++.tbd */; };
|
||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||
BD7041F2826E4A2CBE6CB87D /* RealmJSTests.xctest in Frameworks */ = {isa = PBXBuildFile; fileRef = F79F72C5390646E0A06AAE68 /* RealmJSTests.xctest */; };
|
||||
D91133DCE120440893E2FD2E /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CD8C8B91E0A747B3883A0D56 /* libz.tbd */; };
|
||||
DFCB30DF40F45C00CFBBE07E /* libPods-drip-dripTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-drip-dripTests.a */; };
|
||||
E545887DBE87912F11770AB9 /* libPods-drip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 699D3B3789FC2E5185CB9894 /* libPods-drip.a */; };
|
||||
FAC423E577F555F66C9891E4 /* libPods-drip-dripTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F33CCAAB670FD0D98C5C72DF /* libPods-drip-dripTests.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -54,23 +54,27 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||
00E356EE1AD99517003FC87E /* dripTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = dripTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* dripTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = dripTests.m; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* drip.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = drip.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = drip/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = drip/AppDelegate.mm; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = drip/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = drip/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = drip/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = drip/main.m; sourceTree = "<group>"; };
|
||||
19F6CBCC0A4E27FBF8BF4A61 /* libPods-drip-dripTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-drip-dripTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2B1578D5817F46EE9BFC9BAF /* Pods-drip.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drip.debug.xcconfig"; path = "Target Support Files/Pods-drip/Pods-drip.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3B4392A12AC88292D35C810B /* Pods-drip.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drip.debug.xcconfig"; path = "Target Support Files/Pods-drip/Pods-drip.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
4A9B2D77CAC90DFEB5C4565A /* Pods-dripTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-dripTests.debug.xcconfig"; path = "Target Support Files/Pods-dripTests/Pods-dripTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
5409189625AB725F00086AE1 /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-LightItalic.ttf"; path = "../../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = "<group>"; };
|
||||
540918A225AB725F00086AE1 /* Prompt-ExtraLight.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Prompt-ExtraLight.ttf"; path = "../../assets/fonts/Prompt-ExtraLight.ttf"; sourceTree = "<group>"; };
|
||||
540918A325AB725F00086AE1 /* OpenSans-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Light.ttf"; path = "../../assets/fonts/OpenSans-Light.ttf"; sourceTree = "<group>"; };
|
||||
540918A425AB725F00086AE1 /* Jost-700-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Jost-700-Bold.otf"; path = "../../assets/fonts/Jost-700-Bold.otf"; sourceTree = "<group>"; };
|
||||
540918A525AB725F00086AE1 /* Menu.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = Menu.ttf; path = ../../assets/fonts/Menu.ttf; sourceTree = "<group>"; };
|
||||
540918A625AB726000086AE1 /* drip-home-icons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "drip-home-icons.ttf"; path = "../../assets/fonts/drip-home-icons.ttf"; sourceTree = "<group>"; };
|
||||
540918A725AB726000086AE1 /* Jost-400-Book.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Jost-400-Book.otf"; path = "../../assets/fonts/Jost-400-Book.otf"; sourceTree = "<group>"; };
|
||||
540918A825AB726000086AE1 /* drip-icon-font.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "drip-icon-font.ttf"; path = "../../assets/fonts/drip-icon-font.ttf"; sourceTree = "<group>"; };
|
||||
540918A925AB726000086AE1 /* OpenSans-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-SemiBold.ttf"; path = "../../assets/fonts/OpenSans-SemiBold.ttf"; sourceTree = "<group>"; };
|
||||
5472A44125BB7806005E81DE /* drip-home-icons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "drip-home-icons.ttf"; path = "../assets/fonts/drip-home-icons.ttf"; sourceTree = "<group>"; };
|
||||
5472A44225BB7806005E81DE /* OpenSans-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Light.ttf"; path = "../assets/fonts/OpenSans-Light.ttf"; sourceTree = "<group>"; };
|
||||
@@ -82,24 +86,28 @@
|
||||
5472A44825BB7806005E81DE /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-LightItalic.ttf"; path = "../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = "<group>"; };
|
||||
5472A44925BB7806005E81DE /* drip-icon-font.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "drip-icon-font.ttf"; path = "../assets/fonts/drip-icon-font.ttf"; sourceTree = "<group>"; };
|
||||
5472A45C25BB7C42005E81DE /* Entypo.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = Entypo.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = "<group>"; };
|
||||
5488D8D628ABF478008DD66D /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = drip/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
548C3D3A2898FB0600013449 /* drip-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "drip-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
54DFE73925D94D6E0025C3FC /* swipe.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = swipe.png; path = ../assets/swipe.png; sourceTree = "<group>"; };
|
||||
54DFE73C25D94DED0025C3FC /* cycle-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "cycle-icon.png"; path = "../assets/cycle-icon.png"; sourceTree = "<group>"; };
|
||||
5709B34CF0A7D63546082F79 /* Pods-drip.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drip.release.xcconfig"; path = "Target Support Files/Pods-drip/Pods-drip.release.xcconfig"; sourceTree = "<group>"; };
|
||||
5B7EB9410499542E8C5724F5 /* Pods-drip-dripTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drip-dripTests.debug.xcconfig"; path = "Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
54E1D49823E7588F003FA37B /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
5ABC2C1190B4D25AC0398D09 /* Pods-dripTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-dripTests.release.xcconfig"; path = "Target Support Files/Pods-dripTests/Pods-dripTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
5C649EDC281151BC005FED46 /* dripRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = dripRelease.entitlements; path = drip/dripRelease.entitlements; sourceTree = "<group>"; };
|
||||
5DCACB8F33CDC322A6C60F78 /* libPods-drip.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-drip.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
699D3B3789FC2E5185CB9894 /* libPods-drip.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-drip.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6B7C2A0A7AAA83BBEFBD0B6A /* libPods-drip-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-drip-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
72DDDE8D34518ED64FD7EBBA /* Pods-drip-dripTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drip-dripTests.release.xcconfig"; path = "Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
7A5827160B914D2B99C47381 /* libRealmReact.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRealmReact.a; sourceTree = "<group>"; };
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = drip/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
84CCEBD3B2C44758853BC941 /* libRNFS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFS.a; sourceTree = "<group>"; };
|
||||
89C6BE57DB24E9ADA2F236DE /* Pods-drip-dripTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drip-dripTests.release.xcconfig"; path = "Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
90224CB4571D41C4969E9722 /* libGCDWebServers.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libGCDWebServers.a; sourceTree = "<group>"; };
|
||||
9AEBF0735214455AAEDF56D5 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
||||
A8B59389C2FC4F19BD30ABC3 /* libRNShare.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNShare.a; sourceTree = "<group>"; };
|
||||
AB636AA0286D45CE9B23B2C3 /* libRCTRestart.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTRestart.a; sourceTree = "<group>"; };
|
||||
B6FD0A300273E09D74C14C19 /* Pods-drip-dripTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drip-dripTests.debug.xcconfig"; path = "Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
CD8C8B91E0A747B3883A0D56 /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
D211D71BE5A8436A978770A9 /* libRNDocumentPicker.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNDocumentPicker.a; sourceTree = "<group>"; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
E086AB579387F878A2CBCFEB /* libPods-drip-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-drip-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E1C5175D0AEA2ABCC690D6E2 /* Pods-drip.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drip.release.xcconfig"; path = "Target Support Files/Pods-drip/Pods-drip.release.xcconfig"; sourceTree = "<group>"; };
|
||||
F33CCAAB670FD0D98C5C72DF /* libPods-drip-dripTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-drip-dripTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F5039D0A572B4BBCB7995891 /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNVectorIcons.a; sourceTree = "<group>"; };
|
||||
F710D85E391D4094816E1B62 /* libRealmJS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRealmJS.a; sourceTree = "<group>"; };
|
||||
F79F72C5390646E0A06AAE68 /* RealmJSTests.xctest */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = RealmJSTests.xctest; sourceTree = "<group>"; };
|
||||
@@ -110,7 +118,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DFCB30DF40F45C00CFBBE07E /* libPods-drip-dripTests.a in Frameworks */,
|
||||
FAC423E577F555F66C9891E4 /* libPods-drip-dripTests.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -118,11 +126,11 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
54E1D49923E7588F003FA37B /* BuildFile in Frameworks */,
|
||||
54E1D49923E7588F003FA37B /* JavaScriptCore.framework in Frameworks */,
|
||||
62F2A4645AC84CDC9506FF27 /* libc++.tbd in Frameworks */,
|
||||
D91133DCE120440893E2FD2E /* libz.tbd in Frameworks */,
|
||||
BD7041F2826E4A2CBE6CB87D /* RealmJSTests.xctest in Frameworks */,
|
||||
0C80B921A6F3F58F76C31292 /* libPods-drip.a in Frameworks */,
|
||||
E545887DBE87912F11770AB9 /* libPods-drip.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -168,12 +176,13 @@
|
||||
13B07FAE1A68108700A75B9A /* drip */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5488D8D628ABF478008DD66D /* LaunchScreen.storyboard */,
|
||||
5C649EDC281151BC005FED46 /* dripRelease.entitlements */,
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
548C3D3A2898FB0600013449 /* drip-Bridging-Header.h */,
|
||||
);
|
||||
@@ -183,12 +192,14 @@
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||
54E1D49823E7588F003FA37B /* JavaScriptCore.framework */,
|
||||
2D16E6891FA4F8E400B85C8A /* libReact.a */,
|
||||
9AEBF0735214455AAEDF56D5 /* libc++.tbd */,
|
||||
CD8C8B91E0A747B3883A0D56 /* libz.tbd */,
|
||||
5DCACB8F33CDC322A6C60F78 /* libPods-drip.a */,
|
||||
19F6CBCC0A4E27FBF8BF4A61 /* libPods-drip-dripTests.a */,
|
||||
6B7C2A0A7AAA83BBEFBD0B6A /* libPods-drip-tvOS.a */,
|
||||
E086AB579387F878A2CBCFEB /* libPods-drip-tvOSTests.a */,
|
||||
699D3B3789FC2E5185CB9894 /* libPods-drip.a */,
|
||||
F33CCAAB670FD0D98C5C72DF /* libPods-drip-dripTests.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -205,16 +216,32 @@
|
||||
90224CB4571D41C4969E9722 /* libGCDWebServers.a */,
|
||||
F710D85E391D4094816E1B62 /* libRealmJS.a */,
|
||||
F79F72C5390646E0A06AAE68 /* RealmJSTests.xctest */,
|
||||
540918A325AB725F00086AE1 /* OpenSans-Light.ttf */,
|
||||
540918A925AB726000086AE1 /* OpenSans-SemiBold.ttf */,
|
||||
540918A725AB726000086AE1 /* Jost-400-Book.otf */,
|
||||
540918A525AB725F00086AE1 /* Menu.ttf */,
|
||||
540918A625AB726000086AE1 /* drip-home-icons.ttf */,
|
||||
540918A425AB725F00086AE1 /* Jost-700-Bold.otf */,
|
||||
);
|
||||
name = "Recovered References";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6817ABC38854EEB6D3EE933A /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
540918A625AB726000086AE1 /* drip-home-icons.ttf */,
|
||||
540918A825AB726000086AE1 /* drip-icon-font.ttf */,
|
||||
540918A725AB726000086AE1 /* Jost-400-Book.otf */,
|
||||
540918A425AB725F00086AE1 /* Jost-700-Bold.otf */,
|
||||
540918A525AB725F00086AE1 /* Menu.ttf */,
|
||||
540918A325AB725F00086AE1 /* OpenSans-Light.ttf */,
|
||||
5409189625AB725F00086AE1 /* OpenSans-LightItalic.ttf */,
|
||||
540918A925AB726000086AE1 /* OpenSans-SemiBold.ttf */,
|
||||
540918A225AB725F00086AE1 /* Prompt-ExtraLight.ttf */,
|
||||
2B1578D5817F46EE9BFC9BAF /* Pods-drip.debug.xcconfig */,
|
||||
E1C5175D0AEA2ABCC690D6E2 /* Pods-drip.release.xcconfig */,
|
||||
4A9B2D77CAC90DFEB5C4565A /* Pods-dripTests.debug.xcconfig */,
|
||||
5ABC2C1190B4D25AC0398D09 /* Pods-dripTests.release.xcconfig */,
|
||||
B6FD0A300273E09D74C14C19 /* Pods-drip-dripTests.debug.xcconfig */,
|
||||
72DDDE8D34518ED64FD7EBBA /* Pods-drip-dripTests.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -231,7 +258,7 @@
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||
42C7F9942202468200F22656 /* Recovered References */,
|
||||
BBD78D7AC51CEA395F1C20DB /* Pods */,
|
||||
6817ABC38854EEB6D3EE933A /* Pods */,
|
||||
006C39A0B9774387BC5ACA43 /* Resources */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
@@ -248,17 +275,6 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B4392A12AC88292D35C810B /* Pods-drip.debug.xcconfig */,
|
||||
5709B34CF0A7D63546082F79 /* Pods-drip.release.xcconfig */,
|
||||
5B7EB9410499542E8C5724F5 /* Pods-drip-dripTests.debug.xcconfig */,
|
||||
89C6BE57DB24E9ADA2F236DE /* Pods-drip-dripTests.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -266,12 +282,11 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "dripTests" */;
|
||||
buildPhases = (
|
||||
A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */,
|
||||
CD68B565C5F4A7A674494D02 /* [CP] Check Pods Manifest.lock */,
|
||||
00E356EA1AD99517003FC87E /* Sources */,
|
||||
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||
00E356EC1AD99517003FC87E /* Resources */,
|
||||
C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */,
|
||||
F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */,
|
||||
46313D848A7A3E69E5ED05E7 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -287,21 +302,19 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "drip" */;
|
||||
buildPhases = (
|
||||
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
|
||||
FD10A7F022414F080027D42C /* Start Packager */,
|
||||
852A2E0CD5D0F561CE2927A3 /* [CP] Check Pods Manifest.lock */,
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
|
||||
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
|
||||
616E70055A3365D214C7B201 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = drip;
|
||||
productName = drip;
|
||||
productName = "Hello World";
|
||||
productReference = 13B07F961A680F5B00A75B9A /* drip.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
@@ -311,7 +324,7 @@
|
||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1430;
|
||||
LastUpgradeCheck = 1340;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
00E356ED1AD99517003FC87E = {
|
||||
@@ -319,12 +332,13 @@
|
||||
TestTargetID = 13B07F861A680F5B00A75B9A;
|
||||
};
|
||||
13B07F861A680F5B00A75B9A = {
|
||||
LastSwiftMigration = 1120;
|
||||
DevelopmentTeam = 6AD72X6W26;
|
||||
LastSwiftMigration = 1340;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "drip" */;
|
||||
compatibilityVersion = "Xcode 12.0";
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
@@ -369,7 +383,7 @@
|
||||
5472A44C25BB7807005E81DE /* OpenSans-Light.ttf in Resources */,
|
||||
5472A45425BB7807005E81DE /* Menu.ttf in Resources */,
|
||||
5472A45A25BB7807005E81DE /* drip-icon-font.ttf in Resources */,
|
||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
|
||||
5488D8D728ABF478008DD66D /* LaunchScreen.storyboard in Resources */,
|
||||
5472A45825BB7807005E81DE /* OpenSans-LightItalic.ttf in Resources */,
|
||||
5472A45625BB7807005E81DE /* OpenSans-SemiBold.ttf in Resources */,
|
||||
5472A45025BB7807005E81DE /* Jost-400-Book.otf in Resources */,
|
||||
@@ -391,56 +405,115 @@
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"$(SRCROOT)/.xcode.env.local",
|
||||
"$(SRCROOT)/.xcode.env",
|
||||
);
|
||||
name = "Bundle React Native code and images";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
|
||||
};
|
||||
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
|
||||
46313D848A7A3E69E5ED05E7 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip/Pods-drip-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip/Pods-drip-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-drip/Pods-drip-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests-resources.sh",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Feather.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Foundation.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-drip-dripTests-checkManifestLockResult.txt",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Feather.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Brands.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Regular.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Solid.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Fontisto.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Foundation.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Ionicons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialCommunityIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
|
||||
616E70055A3365D214C7B201 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip/Pods-drip-resources.sh",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Feather.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Foundation.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Feather.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Brands.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Regular.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Solid.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Fontisto.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Foundation.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Ionicons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialCommunityIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-drip/Pods-drip-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
852A2E0CD5D0F561CE2927A3 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@@ -462,58 +535,7 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip/Pods-drip-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip/Pods-drip-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-drip/Pods-drip-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-drip-dripTests/Pods-drip-dripTests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||
CD68B565C5F4A7A674494D02 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@@ -521,15 +543,18 @@
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "Start Packager";
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-drip-dripTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
@@ -547,7 +572,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -565,20 +590,36 @@
|
||||
/* Begin XCBuildConfiguration section */
|
||||
00E356F61AD99517003FC87E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-drip-dripTests.debug.xcconfig */;
|
||||
baseConfigurationReference = B6FD0A300273E09D74C14C19 /* Pods-drip-dripTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
ENABLE_BITCODE = "$(inherited)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/react-native-svg/ios/**",
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/realm/src/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-share/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-document-picker/ios/RNDocumentPicker",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-restart/ios/RCTRestart/**",
|
||||
"$(SRCROOT)/../node_modules/realm/src/**",
|
||||
);
|
||||
INFOPLIST_FILE = dripTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
@@ -593,17 +634,33 @@
|
||||
};
|
||||
00E356F71AD99517003FC87E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-drip-dripTests.release.xcconfig */;
|
||||
baseConfigurationReference = 72DDDE8D34518ED64FD7EBBA /* Pods-drip-dripTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_BITCODE = "$(inherited)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/react-native-svg/ios/**",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/realm/src/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-share/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-document-picker/ios/RNDocumentPicker",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-restart/ios/RCTRestart/**",
|
||||
"$(SRCROOT)/../node_modules/realm/src/**",
|
||||
);
|
||||
INFOPLIST_FILE = dripTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
@@ -618,25 +675,77 @@
|
||||
};
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-drip.debug.xcconfig */;
|
||||
baseConfigurationReference = 2B1578D5817F46EE9BFC9BAF /* Pods-drip.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = 6AD72X6W26;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = drip/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
ENABLE_BITCODE = "$(inherited)";
|
||||
EXCLUDED_ARCHS = "";
|
||||
"EXCLUDED_ARCHS[sdk=*]" = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"COCOAPODS=1",
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/realm/src/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-share/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-document-picker/ios/RNDocumentPicker",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-restart/ios/RCTRestart/**",
|
||||
"$(SRCROOT)/../node_modules/@react-native-community/push-notification-ios/ios",
|
||||
"$(SRCROOT)/../node_modules/realm/src/**",
|
||||
);
|
||||
INFOPLIST_FILE = drip/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/Folly\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/GCDWebServer\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNFS\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNShare\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-Core\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsi\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RealmJS\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/Yoga\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/glog\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-restart\"",
|
||||
"\"${PODS_ROOT}/../../node_modules/realm/vendor/realm-ios\"",
|
||||
"$(inherited)",
|
||||
);
|
||||
MARKETING_VERSION = 1.2208.11;
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
"$(inherited)",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.heartofcode.drip.cycle.tracking;
|
||||
PRODUCT_NAME = drip;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "drip-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@@ -645,24 +754,76 @@
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-drip.release.xcconfig */;
|
||||
baseConfigurationReference = E1C5175D0AEA2ABCC690D6E2 /* Pods-drip.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = drip/dripRelease.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 6AD72X6W26;
|
||||
INFOPLIST_FILE = drip/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
ENABLE_BITCODE = "$(inherited)";
|
||||
EXCLUDED_ARCHS = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"COCOAPODS=1",
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/realm/src/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-share/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-document-picker/ios/RNDocumentPicker",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-restart/ios/RCTRestart/**",
|
||||
"$(SRCROOT)/../node_modules/@react-native-community/push-notification-ios/ios",
|
||||
"$(SRCROOT)/../node_modules/realm/src/**",
|
||||
);
|
||||
INFOPLIST_FILE = drip/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/FBReactNativeSpec\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/Folly\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/GCDWebServer\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNFS\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNShare\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNVectorIcons\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-Core\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTActionSheet\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsi\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/RealmJS\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/Yoga\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/glog\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-document-picker\"",
|
||||
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-restart\"",
|
||||
"\"${PODS_ROOT}/../../node_modules/realm/vendor/realm-ios\"",
|
||||
"$(inherited)",
|
||||
);
|
||||
MARKETING_VERSION = 1.2208.11;
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
"$(inherited)",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.heartofcode.drip.cycle.tracking;
|
||||
PRODUCT_NAME = drip;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "drip-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
@@ -673,7 +834,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -699,6 +860,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_BITCODE = "$(inherited)";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
@@ -718,24 +880,15 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(SDKROOT)/usr/lib/swift\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
"$(SDKROOT)/usr/lib/swift",
|
||||
"\"$(inherited)\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-DFOLLY_NO_CONFIG",
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_WORKSPACE = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -744,7 +897,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -770,6 +923,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_BITCODE = "$(inherited)";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
@@ -782,24 +936,15 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(SDKROOT)/usr/lib/swift\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
"$(SDKROOT)/usr/lib/swift",
|
||||
"\"$(inherited)\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-DFOLLY_NO_CONFIG",
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VALIDATE_WORKSPACE = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1430"
|
||||
LastUpgradeVersion = "1210"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#import <React/RCTBridgeDelegate.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <UserNotifications/UNUserNotificationCenter.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#import <AppDelegate.h>
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#import <RNCPushNotificationIOS.h>
|
||||
|
||||
// #ifdef FB_SONARKIT_ENABLED
|
||||
// #import <FlipperKit/FlipperClient.h>
|
||||
// #import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
|
||||
// #import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
|
||||
// #import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
|
||||
// #import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
|
||||
// #import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
|
||||
// static void InitializeFlipper(UIApplication *application) {
|
||||
// FlipperClient *client = [FlipperClient sharedClient];
|
||||
// SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
|
||||
// [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
|
||||
// [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
|
||||
// [client addPlugin:[FlipperKitReactPlugin new]];
|
||||
// [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
|
||||
// [client start];
|
||||
// }
|
||||
// #endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
// #ifdef FB_SONARKIT_ENABLED
|
||||
// InitializeFlipper(application);
|
||||
// #endif
|
||||
|
||||
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
|
||||
moduleName:@"drip"
|
||||
initialProperties:nil];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
rootView.backgroundColor = [UIColor systemBackgroundColor];
|
||||
} else {
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
// Define UNUserNotificationCenter
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
center.delegate = self;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
//Called when a notification is delivered to a foreground app.
|
||||
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
|
||||
{
|
||||
completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
|
||||
}
|
||||
|
||||
// Required for the register event.
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
||||
}
|
||||
// Required for the notification event. You must call the completion handler after handling the remote notification.
|
||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
|
||||
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
||||
}
|
||||
// Required for the registrationError event.
|
||||
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
||||
{
|
||||
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
|
||||
}
|
||||
// Required for localNotification event
|
||||
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
|
||||
didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||
withCompletionHandler:(void (^)(void))completionHandler
|
||||
{
|
||||
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
|
||||
}
|
||||
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,108 +0,0 @@
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <React/RCTCxxBridgeDelegate.h>
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <React/RCTSurfacePresenter.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTAppSetupPrepareApp(application);
|
||||
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"drip", nil);
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
rootView.backgroundColor = [UIColor systemBackgroundColor];
|
||||
} else {
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
}
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
- (Class)getModuleClassFromName:(const char *)name
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
initParams:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||
{
|
||||
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
@@ -1,62 +1,62 @@
|
||||
{
|
||||
"images": [
|
||||
"images" : [
|
||||
{
|
||||
"filename": "40 1.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "20x20"
|
||||
"filename" : "40.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename": "60 1.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "20x20"
|
||||
"filename" : "60.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename": "58 1.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "29x29"
|
||||
"filename" : "58.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename": "87 1.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "29x29"
|
||||
"filename" : "87.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename": "80 1.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "40x40"
|
||||
"filename" : "80.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename": "120 2.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "40x40"
|
||||
"filename" : "120.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename": "120 1.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "2x",
|
||||
"size": "60x60"
|
||||
"filename" : "120-1.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename": "180 1.png",
|
||||
"idiom": "iphone",
|
||||
"scale": "3x",
|
||||
"size": "60x60"
|
||||
"filename" : "180.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename": "appstore 1.png",
|
||||
"idiom": "ios-marketing",
|
||||
"scale": "1x",
|
||||
"size": "1024x1024"
|
||||
"filename" : "appstore.png",
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 43 KiB |
@@ -8,10 +8,8 @@
|
||||
<string>drip.</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>AppIcon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.heartofcode.drip.cycle.tracking</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
@@ -19,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.2410.22</string>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
@implementation dripTests
|
||||
|
||||
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
|
||||
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
|
||||
{
|
||||
if (test(view)) {
|
||||
return YES;
|
||||
@@ -34,25 +34,23 @@
|
||||
|
||||
__block NSString *redboxError = nil;
|
||||
#ifdef DEBUG
|
||||
RCTSetLogFunction(
|
||||
^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
|
||||
if (level >= RCTLogLevelError) {
|
||||
redboxError = message;
|
||||
}
|
||||
});
|
||||
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
|
||||
if (level >= RCTLogLevelError) {
|
||||
redboxError = message;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
|
||||
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
|
||||
foundElement = [self findSubviewInView:vc.view
|
||||
matching:^BOOL(UIView *view) {
|
||||
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}];
|
||||
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
|
||||
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -63,4 +61,5 @@
|
||||
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,6 +3,8 @@ import { getCycleLengthStats } from './cycle-length'
|
||||
const LocalDate = joda.LocalDate
|
||||
const DAYS = joda.ChronoUnit.DAYS
|
||||
|
||||
const toJSON = (realmObj) => JSON.parse(JSON.stringify(realmObj))
|
||||
|
||||
export default function config(opts) {
|
||||
let bleedingDaysSortedByDate
|
||||
let cycleStartsSortedByDate
|
||||
@@ -14,10 +16,13 @@ export default function config(opts) {
|
||||
if (!opts) {
|
||||
// we only want to require (and run) the db module
|
||||
// when not running the tests
|
||||
bleedingDaysSortedByDate = require('../db').getBleedingDaysSortedByDate()
|
||||
cycleStartsSortedByDate = require('../db').getCycleStartsSortedByDate()
|
||||
cycleDaysSortedByDate = require('../db').getCycleDaysSortedByDate()
|
||||
|
||||
bleedingDaysSortedByDate = toJSON(
|
||||
require('../db').getBleedingDaysSortedByDate()
|
||||
)
|
||||
cycleStartsSortedByDate = toJSON(
|
||||
require('../db').getCycleStartsSortedByDate()
|
||||
)
|
||||
cycleDaysSortedByDate = toJSON(require('../db').getCycleDaysSortedByDate())
|
||||
maxBreakInBleeding = 1
|
||||
maxCycleLength = 99
|
||||
minCyclesForPrediction = 3
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default function getNfpMucus(feeling, texture) {
|
||||
export default function getSensiplanMucus(feeling, texture) {
|
||||
if (typeof feeling != 'number' || typeof texture != 'number') return null
|
||||
|
||||
const feelingMapping = {
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import { Platform } from 'react-native'
|
||||
import {
|
||||
tempReminderObservable,
|
||||
periodReminderObservable,
|
||||
advanceNoticeDaysObservable,
|
||||
} from '../local-storage'
|
||||
import * as PN from 'react-native-push-notification'
|
||||
import { requestNotifications } from 'react-native-permissions'
|
||||
import Notification from 'react-native-push-notification'
|
||||
import Moment from 'moment'
|
||||
import { LocalDate } from '@js-joda/core'
|
||||
|
||||
@@ -14,30 +11,11 @@ import { getBleedingDaysSortedByDate } from '../db'
|
||||
import cycleModule from './cycle'
|
||||
import nothingChanged from '../db/db-unchanged'
|
||||
|
||||
const DRIP_CHANNEL_ID = 'drip-channel-id'
|
||||
const TEMPERATURE_REMINDER_ID = '1'
|
||||
const PERIOD_REMINDER_ID = '2'
|
||||
const PushNotification = Platform.OS === 'ios' ? PN : PN.default
|
||||
|
||||
export default function setupNotifications(navigate, setDate) {
|
||||
// for Android, this method call is necessary
|
||||
if (Platform.OS === 'android') {
|
||||
requestNotifications()
|
||||
}
|
||||
|
||||
PushNotification.createChannel({
|
||||
channelId: DRIP_CHANNEL_ID, // (required)
|
||||
channelName: 'drip reminder', // (required)
|
||||
playSound: false, // (optional) default: true
|
||||
})
|
||||
|
||||
PushNotification.configure({
|
||||
Notification.configure({
|
||||
onNotification: (notification) => {
|
||||
// https://github.com/zo0r/react-native-push-notification/issues/966#issuecomment-479069106
|
||||
if (
|
||||
notification.data?.id === TEMPERATURE_REMINDER_ID ||
|
||||
notification.id === TEMPERATURE_REMINDER_ID
|
||||
) {
|
||||
if (notification.data?.id === '1' || notification.id === '1') {
|
||||
const todayDate = LocalDate.now().toString()
|
||||
setDate(todayDate)
|
||||
navigate('TemperatureEditView')
|
||||
@@ -48,7 +26,7 @@ export default function setupNotifications(navigate, setDate) {
|
||||
})
|
||||
|
||||
tempReminderObservable((reminder) => {
|
||||
PushNotification.cancelLocalNotification({ id: TEMPERATURE_REMINDER_ID })
|
||||
Notification.cancelLocalNotifications({ id: '1' })
|
||||
if (reminder.enabled) {
|
||||
const [hours, minutes] = reminder.time.split(':')
|
||||
let target = new Moment()
|
||||
@@ -60,76 +38,54 @@ export default function setupNotifications(navigate, setDate) {
|
||||
target = target.add(1, 'd')
|
||||
}
|
||||
|
||||
PushNotification.localNotificationSchedule({
|
||||
id: TEMPERATURE_REMINDER_ID,
|
||||
userInfo: { id: TEMPERATURE_REMINDER_ID },
|
||||
Notification.localNotificationSchedule({
|
||||
id: '1',
|
||||
userInfo: { id: '1' },
|
||||
message: labels.tempReminder.notification,
|
||||
date: target.toDate(),
|
||||
vibrate: false,
|
||||
repeatType: 'day',
|
||||
channelId: DRIP_CHANNEL_ID,
|
||||
allowWhileIdle: true,
|
||||
})
|
||||
}
|
||||
}, false)
|
||||
|
||||
periodReminderObservable(() => updatePeriodNotification(), false)
|
||||
advanceNoticeDaysObservable(() => updatePeriodNotification(), false)
|
||||
periodReminderObservable((reminder) => {
|
||||
Notification.cancelLocalNotifications({ id: '2' })
|
||||
if (reminder.enabled) setupPeriodReminder()
|
||||
}, false)
|
||||
|
||||
getBleedingDaysSortedByDate().addListener((_, changes) => {
|
||||
// the listener fires on setup, so we check if there were actually any changes
|
||||
if (nothingChanged(changes)) {
|
||||
return
|
||||
}
|
||||
|
||||
updatePeriodNotification()
|
||||
if (nothingChanged(changes)) return
|
||||
Notification.cancelLocalNotifications({ id: '2' })
|
||||
if (periodReminderObservable.value.enabled) setupPeriodReminder()
|
||||
})
|
||||
}
|
||||
|
||||
const updatePeriodNotification = () => {
|
||||
// Cancel any existing period reminder
|
||||
PushNotification.cancelLocalNotification({ id: PERIOD_REMINDER_ID })
|
||||
|
||||
// Set up a new period reminder if enabled
|
||||
if (periodReminderObservable.value.enabled) {
|
||||
schedulePeriodNotification()
|
||||
}
|
||||
}
|
||||
|
||||
function schedulePeriodNotification() {
|
||||
function setupPeriodReminder() {
|
||||
const bleedingPrediction = cycleModule().getPredictedMenses()
|
||||
|
||||
if (bleedingPrediction.length > 0) {
|
||||
const predictedBleedingStart = Moment(
|
||||
bleedingPrediction[0][0],
|
||||
'YYYY-MM-DD'
|
||||
)
|
||||
|
||||
const advanceNoticeDays = parseInt(advanceNoticeDaysObservable.value)
|
||||
|
||||
// ${advanceNoticeDays} days before and at 6 am
|
||||
// 3 days before and at 6 am
|
||||
const reminderDate = predictedBleedingStart
|
||||
.subtract(advanceNoticeDays, 'days')
|
||||
.subtract(3, 'days')
|
||||
.hours(6)
|
||||
.minutes(0)
|
||||
.seconds(0)
|
||||
|
||||
if (reminderDate.isAfter()) {
|
||||
// period is likely to start in advanceNoticeDays to advanceNoticeDays + (length of prediction - 1) days
|
||||
const daysToEndOfPrediction =
|
||||
advanceNoticeDays + bleedingPrediction[0].length - 1
|
||||
// period is likely to start in 3 to 3 + (length of prediction - 1) days
|
||||
const daysToEndOfPrediction = bleedingPrediction[0].length + 2
|
||||
|
||||
PushNotification.localNotificationSchedule({
|
||||
id: PERIOD_REMINDER_ID,
|
||||
userInfo: { id: PERIOD_REMINDER_ID },
|
||||
message: labels.periodReminder.notification(
|
||||
advanceNoticeDays,
|
||||
daysToEndOfPrediction
|
||||
),
|
||||
Notification.localNotificationSchedule({
|
||||
id: '2',
|
||||
userInfo: { id: '2' },
|
||||
message: labels.periodReminder.notification(daysToEndOfPrediction),
|
||||
date: reminderDate.toDate(),
|
||||
vibrate: false,
|
||||
channelId: DRIP_CHANNEL_ID,
|
||||
allowWhileIdle: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
import getFertilityStatus from 'sympto'
|
||||
import cycleModule from './cycle'
|
||||
import { fertilityTrackingObservable, useCervixAsSecondarySymptomObservable } from '../local-storage'
|
||||
import { useCervixObservable } from '../local-storage'
|
||||
import { fertilityStatus as labels } from '../i18n/en/labels'
|
||||
|
||||
const isFertilityTrackingEnabled = fertilityTrackingObservable.value
|
||||
|
||||
export function getFertilityStatusForDay(dateString) {
|
||||
if (!isFertilityTrackingEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
const status = getCycleStatusForDay(dateString)
|
||||
if (!status) return {
|
||||
status: labels.fertile,
|
||||
@@ -40,10 +34,6 @@ export function getFertilityStatusForDay(dateString) {
|
||||
}
|
||||
|
||||
export function getCycleStatusForDay(dateString, opts = {}) {
|
||||
if (!isFertilityTrackingEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
const {
|
||||
getCycleForDay,
|
||||
getCyclesBefore,
|
||||
@@ -67,7 +57,7 @@ export function getCycleStatusForDay(dateString, opts = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
cycleInfo.secondarySymptom = useCervixAsSecondarySymptomObservable.value ? 'cervix' : 'mucus'
|
||||
cycleInfo.secondarySymptom = useCervixObservable.value ? 'cervix' : 'mucus'
|
||||
|
||||
return getFertilityStatus(cycleInfo)
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import Observable from 'obv'
|
||||
import { TEMP_SCALE_MIN, TEMP_SCALE_MAX, TEMP_SCALE_UNITS } from './config'
|
||||
|
||||
import { ADVANCE_PERIOD_NOTICE_DAYS_INIT_VALUE } from './config'
|
||||
|
||||
export const scaleObservable = Observable()
|
||||
setObvWithInitValue('tempScale', scaleObservable, {
|
||||
min: TEMP_SCALE_MIN,
|
||||
@@ -46,46 +44,12 @@ export async function savePeriodReminder(reminder) {
|
||||
periodReminderObservable.set(reminder)
|
||||
}
|
||||
|
||||
export const periodPredictionObservable = Observable()
|
||||
setObvWithInitValue('periodPrediction', periodPredictionObservable, true)
|
||||
export const useCervixObservable = Observable()
|
||||
setObvWithInitValue('useCervix', useCervixObservable, false)
|
||||
|
||||
export async function savePeriodPrediction(bool) {
|
||||
await AsyncStorage.setItem('periodPrediction', JSON.stringify(bool))
|
||||
periodPredictionObservable.set(bool)
|
||||
|
||||
if (!periodPredictionObservable.value) {
|
||||
const result = await AsyncStorage.getItem('periodReminder')
|
||||
if (JSON.parse(result).enabled) {
|
||||
periodReminderObservable.set(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const advanceNoticeDaysObservable = Observable()
|
||||
setObvWithInitValue(
|
||||
'advanceNoticeDays',
|
||||
advanceNoticeDaysObservable,
|
||||
parseInt(ADVANCE_PERIOD_NOTICE_DAYS_INIT_VALUE)
|
||||
)
|
||||
|
||||
export async function saveAdvanceNoticeDays(days) {
|
||||
await AsyncStorage.setItem('advanceNoticeDays', JSON.stringify(days))
|
||||
advanceNoticeDaysObservable.set(days)
|
||||
}
|
||||
|
||||
export const useCervixAsSecondarySymptomObservable = Observable()
|
||||
setObvWithInitValue(
|
||||
'useCervixAsSecondarySymptom',
|
||||
useCervixAsSecondarySymptomObservable,
|
||||
0
|
||||
)
|
||||
|
||||
export async function saveUseCervixAsSecondarySymptom(value) {
|
||||
await AsyncStorage.setItem(
|
||||
'useCervixAsSecondarySymptom',
|
||||
JSON.stringify(value)
|
||||
)
|
||||
useCervixAsSecondarySymptomObservable.set(value)
|
||||
export async function saveUseCervix(bool) {
|
||||
await AsyncStorage.setItem('useCervix', JSON.stringify(bool))
|
||||
useCervixObservable.set(bool)
|
||||
}
|
||||
|
||||
export const hasEncryptionObservable = Observable()
|
||||
@@ -113,86 +77,6 @@ export async function setChartFlag() {
|
||||
await AsyncStorage.setItem('isFirstChartView', JSON.stringify(false))
|
||||
}
|
||||
|
||||
export const temperatureTrackingCategoryObservable = Observable()
|
||||
setObvWithInitValue('temperature', temperatureTrackingCategoryObservable, true)
|
||||
|
||||
export async function saveTemperatureTrackingCategory(bool) {
|
||||
await AsyncStorage.setItem('temperature', JSON.stringify(bool))
|
||||
temperatureTrackingCategoryObservable.set(bool)
|
||||
|
||||
if (!temperatureTrackingCategoryObservable.value) {
|
||||
// if temperature tracking is turned off, the temperature reminder gets disabled
|
||||
const tempReminderResult = await AsyncStorage.getItem('tempReminder')
|
||||
if (tempReminderResult && JSON.parse(tempReminderResult).enabled) {
|
||||
tempReminderObservable.set(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const mucusTrackingCategoryObservable = Observable()
|
||||
setObvWithInitValue('mucus', mucusTrackingCategoryObservable, true)
|
||||
|
||||
export async function saveMucusTrackingCategory(bool) {
|
||||
await AsyncStorage.setItem('mucus', JSON.stringify(bool))
|
||||
mucusTrackingCategoryObservable.set(bool)
|
||||
}
|
||||
|
||||
export const cervixTrackingCategoryObservable = Observable()
|
||||
setObvWithInitValue('cervix', cervixTrackingCategoryObservable, true)
|
||||
|
||||
export async function saveCervixTrackingCategory(bool) {
|
||||
await AsyncStorage.setItem('cervix', JSON.stringify(bool))
|
||||
cervixTrackingCategoryObservable.set(bool)
|
||||
}
|
||||
|
||||
export const sexTrackingCategoryObservable = Observable()
|
||||
setObvWithInitValue('sex', sexTrackingCategoryObservable, true)
|
||||
|
||||
export async function saveSexTrackingCategory(bool) {
|
||||
await AsyncStorage.setItem('sex', JSON.stringify(bool))
|
||||
sexTrackingCategoryObservable.set(bool)
|
||||
}
|
||||
|
||||
export const desireTrackingCategoryObservable = Observable()
|
||||
setObvWithInitValue('desire', desireTrackingCategoryObservable, true)
|
||||
|
||||
export async function saveDesireTrackingCategory(bool) {
|
||||
await AsyncStorage.setItem('desire', JSON.stringify(bool))
|
||||
desireTrackingCategoryObservable.set(bool)
|
||||
}
|
||||
|
||||
export const painTrackingCategoryObservable = Observable()
|
||||
setObvWithInitValue('pain', painTrackingCategoryObservable, true)
|
||||
|
||||
export async function savePainTrackingCategory(bool) {
|
||||
await AsyncStorage.setItem('pain', JSON.stringify(bool))
|
||||
painTrackingCategoryObservable.set(bool)
|
||||
}
|
||||
|
||||
export const moodTrackingCategoryObservable = Observable()
|
||||
setObvWithInitValue('mood', moodTrackingCategoryObservable, true)
|
||||
|
||||
export async function saveMoodTrackingCategory(bool) {
|
||||
await AsyncStorage.setItem('mood', JSON.stringify(bool))
|
||||
moodTrackingCategoryObservable.set(bool)
|
||||
}
|
||||
|
||||
export const noteTrackingCategoryObservable = Observable()
|
||||
setObvWithInitValue('note', noteTrackingCategoryObservable, true)
|
||||
|
||||
export async function saveNoteTrackingCategory(bool) {
|
||||
await AsyncStorage.setItem('note', JSON.stringify(bool))
|
||||
noteTrackingCategoryObservable.set(bool)
|
||||
}
|
||||
|
||||
export const fertilityTrackingObservable = Observable()
|
||||
setObvWithInitValue('fertilityTracking', fertilityTrackingObservable, true)
|
||||
|
||||
export async function saveFertilityTrackingEnabled(bool) {
|
||||
await AsyncStorage.setItem('fertilityTracking', JSON.stringify(bool))
|
||||
fertilityTrackingObservable.set(bool)
|
||||
}
|
||||
|
||||
async function setObvWithInitValue(key, obv, defaultValue) {
|
||||
const result = await AsyncStorage.getItem(key)
|
||||
let value
|
||||
|
||||
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 152 KiB |