├── .deepsource.toml
├── .env
├── .expo-shared
└── assets.json
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── issue_template_bugs.md
├── issue_template_features.md
└── pull_request_template.md
├── .gitignore
├── App.js
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── GoogleService-Info.plist
├── LICENSE
├── README.md
├── app.json
├── assets
├── aboutAndProfileScreen.gif
├── accurate.png
├── adaptive-icon.png
├── adfree.png
├── depositphotos_29671351-stock-photo-searching.jpg
├── easytouse.png
├── favicon.png
├── fonts
│ ├── Overpass-Bold.ttf
│ ├── Overpass-ExtraBold.ttf
│ ├── Overpass-Light.ttf
│ └── Ubuntu-Medium.ttf
├── getstarted.png
├── icon.png
├── icons
│ ├── android
│ │ ├── ic_launcher-web.png
│ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-ldpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── playstore-icon.png
│ │ └── values
│ │ │ └── ic_launcher_background.xml
│ └── ios
│ │ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ ├── Icon-App-83.5x83.5@2x.png
│ │ └── ItunesArtwork@2x.png
│ │ ├── iTunesArtwork@1x.png
│ │ ├── iTunesArtwork@2x.png
│ │ └── iTunesArtwork@3x.png
├── loginScreen.gif
├── logo-circle.png
├── logo.png
├── search-result-not-found-2130361-1800925.png
├── searchScreen.gif
├── splash.png
├── stock.png
├── stockScreenAndWatchlist.gif
└── welcome.png
├── babel.config.js
├── components
├── Listcard.js
├── card
│ ├── Card.js
│ └── index.jsx
├── header
│ └── headerLoginPage.js
├── navbar
│ ├── index.jsx
│ └── navbarBottom.js
├── profile
│ └── index.jsx
├── search
│ ├── index.js
│ └── suggestion
│ │ └── index.jsx
└── watchlist
│ ├── index.jsx
│ └── item
│ └── index.jsx
├── eas.json
├── firebase.js
├── google-services.json
├── hooks
└── useAuth.js
├── index.js
├── metro.config.js
├── package.json
├── patches
└── react-native+0.70.5.patch
├── routes
├── StackNavigator.js
└── TabNavigator.js
├── screens
├── AboutScreen.js
├── Intro.js
├── LoginScreen.js
├── ProfileScreen.js
├── SearchScreen.js
├── StockScreen.js
└── WatchListScreen.js
├── shared
├── button.js
└── buttonLogout.js
├── static
└── data
│ └── db.json
├── utils
└── documentation
│ ├── Crypto Data API.md
│ └── Stock news API.md
└── yarn.lock
/.deepsource.toml:
--------------------------------------------------------------------------------
1 | version = 1
2 |
3 | [[analyzers]]
4 | name = "shell"
5 | enabled = true
6 |
7 | [[analyzers]]
8 | name = "javascript"
9 | enabled = true
10 |
11 | [analyzers.meta]
12 | plugins = ["react"]
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | API_KEY=AIzaSyDyjTYFGvcM7PM9D0O_IzEYG5bm2kgoGBY
2 | AUTH_DOMAIN=stock-watchlist-pec.firebaseapp.com
3 | PROJECT_ID=stock-watchlist-pec
4 | STORAGE_BUCKET=stock-watchlist-pec.appspot.com
5 | MESSAGING_SENDER_ID=316148951749
6 | APP_ID=1:316148951749:web:3fed8a95e649e78d605eac
7 | MEASUREMENT_ID=G-BQMYPTRNNX
8 | ANDROID_CLIENT_ID=316148951749-eg5o8km0k13u03b8r32phi6v6f8vr3dn.apps.googleusercontent.com
9 | IOS_CLIENT_ID=316148951749-f92vbdc04mughtfsb8feimdr950aedc1.apps.googleusercontent.com
10 | ANDROID_STANDALONE_APP_CLIENT_ID=316148951749-lj3gsji24t5tb07eqjen9ov3jrpvgcjp.apps.googleusercontent.com
11 | IOS_STANDALONE_APP_CLIENT_ID=316148951749-8u2uof18venstiufjg0q4uv0hnp1i5lh.apps.googleusercontent.com
12 | EXPO_CLIENT_ID=316148951749-qhh8q0ebn8dd5b0hfmlsmokom2bqrlpb.apps.googleusercontent.com
13 | X_MESSARI_API_KEY=9f3cc221-44ec-460a-bf7a-8576d8e6dcf9
14 | PROXY=true
--------------------------------------------------------------------------------
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
3 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
4 | }
5 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | # Prerequisites
11 |
12 | Please answer the following questions for yourself before submitting an issue.
13 |
14 | - [ ] I am running the latest version
15 | - [ ] I checked the documentation and found no answer
16 | - [ ] I checked to make sure that this issue has not already been filed
17 |
18 | # Issue Type: Bug
19 |
20 | Please help provide information about the failure caused by the bug.
21 |
22 | # Expected Behavior
23 |
24 | Please describe the behavior you are expecting
25 |
26 | # Current Behavior
27 |
28 | What is the current behavior?
29 |
30 | ### Steps To Reproduce:
31 |
38 |
39 | ### Environment:
40 |
46 |
47 | ## Failure Logs
48 |
49 | Please include any relevant log snippets or files here.
50 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | # Prerequisites
11 |
12 | Please answer the following questions for yourself before submitting an issue.
13 |
14 | - [ ] I am running the latest version
15 | - [ ] I checked the documentation and found no answer
16 | - [ ] I checked to make sure that this issue has not already been filed
17 |
18 | # Issue Type: Adding Features
19 |
20 | # Expected Behavior
21 |
22 | Please describe the behavior you are expecting
23 |
24 | # Current Behavior
25 |
26 | What is the current behavior?
27 |
28 | ## Context
29 |
30 | Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for certain conditions.
31 |
32 | * Firmware Version:
33 | * Operating System:
34 | * SDK version:
35 | * Toolchain version:
36 |
37 | ## Failure Logs
38 |
39 | Please include any relevant log snippets or files here.
40 |
--------------------------------------------------------------------------------
/.github/issue_template_bugs.md:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 |
3 | Please answer the following questions for yourself before submitting an issue.
4 |
5 | - [ ] I am running the latest version
6 | - [ ] I checked the documentation and found no answer
7 | - [ ] I checked to make sure that this issue has not already been filed
8 |
9 | # Issue Type : Bug
10 |
11 | Please help provide information about the failure caused by the bug.
12 |
13 | # Expected Behavior
14 |
15 | Please describe the behavior you are expecting
16 |
17 | # Current Behavior
18 |
19 | What is the current behavior?
20 |
21 | ### Steps To Reproduce:
22 |
29 |
30 | ### Environment:
31 |
37 |
38 | ## Failure Logs
39 |
40 | Please include any relevant log snippets or files here.
--------------------------------------------------------------------------------
/.github/issue_template_features.md:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 |
3 | Please answer the following questions for yourself before submitting an issue.
4 |
5 | - [ ] I am running the latest version
6 | - [ ] I checked the documentation and found no answer
7 | - [ ] I checked to make sure that this issue has not already been filed
8 |
9 | # Issue Type : Adding Features
10 |
11 | # Expected Behavior
12 |
13 | Please describe the behavior you are expecting
14 |
15 | # Current Behavior
16 |
17 | What is the current behavior?
18 |
19 | ## Context
20 |
21 | Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.
22 |
23 | * Firmware Version:
24 | * Operating System:
25 | * SDK version:
26 | * Toolchain version:
27 |
28 | ## Failure Logs
29 |
30 | Please include any relevant log snippets or files here.
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Description
4 |
5 | Describe the changes you have made.
6 |
7 | ## Issue Resolved
8 |
9 | Link to the issue that is resolved by this pull request goes here e.g. Fixes #09.
10 |
11 | ## Screenshots
12 |
13 | Provide some screenshots of the changes made (if applicable).
14 |
15 | ## Checklist
16 |
17 | Please make sure to review the following before submitting your PR:
18 |
19 |
20 | - [ ] I have read the [contribution guidelines].
21 | - [ ] I have read the code of conduct.
22 | - [ ] I have reviewed my submission in detail.
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | /android/
3 | .expo/
4 | dist/
5 | npm-debug.*
6 | *.jks
7 | *.p8
8 | *.p12
9 | *.key
10 | *.mobileprovision
11 | *.orig.*
12 | web-build/
13 | # .env
14 |
15 | # macOS
16 | .DS_Store
17 |
18 | # @generated expo-cli sync-e7dcf75f4e856f7b6f3239b3f3a7dd614ee755a8
19 | # The following patterns were generated by expo-cli
20 |
21 | # OSX
22 | #
23 | .DS_Store
24 |
25 | # Xcode
26 | #
27 | build/
28 | *.pbxuser
29 | !default.pbxuser
30 | *.mode1v3
31 | !default.mode1v3
32 | *.mode2v3
33 | !default.mode2v3
34 | *.perspectivev3
35 | !default.perspectivev3
36 | xcuserdata
37 | *.xccheckout
38 | *.moved-aside
39 | DerivedData
40 | *.hmap
41 | *.ipa
42 | *.xcuserstate
43 | project.xcworkspace
44 |
45 | # Android/IntelliJ
46 | #
47 | build/
48 | .idea
49 | .vscode
50 | .gradle
51 | local.properties
52 | *.iml
53 | *.hprof
54 |
55 | # node.js
56 | #
57 | node_modules/
58 | npm-debug.log
59 | yarn-error.log
60 |
61 | # BUCK
62 | buck-out/
63 | \.buckd/
64 | *.keystore
65 | !debug.keystore
66 |
67 | # Bundle artifacts
68 | *.jsbundle
69 |
70 | # CocoaPods
71 | /ios/Pods/
72 |
73 | # Expo
74 | .expo/
75 | web-build/
76 | dist/
77 |
78 | # @end expo-cli
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import 'expo-dev-client';
2 | import React from 'react';
3 | import { RootSiblingParent } from 'react-native-root-siblings';
4 | import { NavigationContainer, DefaultTheme } from '@react-navigation/native';
5 | import { Provider as PaperProvider } from 'react-native-paper';
6 | import { LogBox } from 'react-native';
7 | LogBox.ignoreAllLogs();
8 | import StackNavigator from './routes/StackNavigator';
9 | import { AuthProvider } from './hooks/useAuth';
10 |
11 | const MyTheme = {
12 | ...DefaultTheme,
13 | colors: {
14 | ...DefaultTheme.colors,
15 | secondary: 'transparent',
16 | onSurface: '#ffffff',
17 | }
18 | };
19 |
20 | export default function App() {
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | https://www.linkedin.com/company/pec-acm-student-chapter/.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue,
4 | email, or any other method with the owners of this repository before making a change.
5 |
6 | Please note we have a code of conduct, please follow it in all your interactions with the project.
7 |
8 | ## Pull Request Process
9 |
10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a
11 | build.
12 | 2. Update the README.md with details of changes to the interface, this includes new environment
13 | variables, exposed ports, useful file locations and container parameters.
14 | 3. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
15 | do not have permission to do that, you may request the second reviewer to merge it for you.
16 |
--------------------------------------------------------------------------------
/GoogleService-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CLIENT_ID
6 | 316148951749-f92vbdc04mughtfsb8feimdr950aedc1.apps.googleusercontent.com
7 | REVERSED_CLIENT_ID
8 | com.googleusercontent.apps.316148951749-f92vbdc04mughtfsb8feimdr950aedc1
9 | API_KEY
10 | AIzaSyCxzZ3wRYWx04g02r0hsc3o_QHL6YYJizg
11 | GCM_SENDER_ID
12 | 316148951749
13 | PLIST_VERSION
14 | 1
15 | BUNDLE_ID
16 | host.exp.exponent
17 | PROJECT_ID
18 | stock-watchlist-pec
19 | STORAGE_BUCKET
20 | stock-watchlist-pec.appspot.com
21 | IS_ADS_ENABLED
22 |
23 | IS_ANALYTICS_ENABLED
24 |
25 | IS_APPINVITE_ENABLED
26 |
27 | IS_GCM_ENABLED
28 |
29 | IS_SIGNIN_ENABLED
30 |
31 | GOOGLE_APP_ID
32 | 1:316148951749:ios:2fa2fb52fb36ed30605eac
33 |
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 PEC CSS
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | [![Contributors][contributors-shield]][contributors-url]
5 | [![Forks][forks-shield]][forks-url]
6 | [![Stargazers][stars-shield]][stars-url]
7 | [![Issues][issues-shield]][issues-url]
8 | [![MIT License][license-shield]][license-url]
9 | [![LinkedIn][linkedin-shield]][linkedin-url]
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
Stock-Watchlist
19 |
20 |
21 |
Completly Open-Source | Free To Use | Ad-Free
22 |
Asset Watchlist Application for Stocks (NSE & BSE), Cryptocurrencies, Options and Indexes.
23 |
24 |
Explore the docs »
25 |
26 |
View Demo
27 | ·
28 |
Report Bug
29 | ·
30 |
Request Feature
31 |
32 |
33 |
34 |
35 |
36 |
37 | Table of Contents
38 |
39 |
40 | About The Project
41 |
44 |
45 |
46 | Getting Started
47 |
51 |
52 | Usage
53 | Roadmap
54 | How to Contribute
55 | License
56 | Contact
57 | Acknowledgments
58 |
59 |
60 |
61 |
62 |
63 |
64 | ## About The Project
65 |
66 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | ### Built With
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | ## Getting Started
87 |
88 | To get a local copy up and running follow these simple example steps.
89 |
90 | ### Prerequisites
91 |
92 | * npm
93 | ```sh
94 | npm install npm@latest -g
95 | ```
96 |
97 | ### Installation
98 |
99 | _Below is an example of how you can install and set up your app._
100 |
101 |
102 | 1. Clone the repo
103 | ```sh
104 | git clone https://github.com/PEC-CSS/Stock-Watchlist.git
105 | ```
106 | 2. Install NPM packages
107 | ```sh
108 | npm install
109 | ```
110 | or
111 | ```sh
112 | npm install --legacy-peer-deps
113 | ```
114 |
115 |
116 |
117 | ## Usage
118 |
119 | - Start the project
120 | ```sh
121 | npx expo start
122 | ```
123 | - To see changes:
124 | - Browser - click on Run in web browser and use 'Ctrl+Shift+M' to toggle mobile view
125 | - Mobile - Scan the QR Code. (make sure Expo Go app is installed on your phone)
126 | - Create a new build
127 | ```sh
128 | eas build --profile preview --platform android
129 | ```
130 |
131 | _For more examples, please refer to the [Documentation](https://example.com)_
132 |
133 |
134 |
135 |
136 |
145 |
146 | ## Contributors
147 | This project exists thanks to all the people who contribute. [Contributing ].
148 |
149 |
150 |
151 |
152 |
153 | See the [open issues](https://github.com/PEC-CSS/Stock-Watchlist/issues) for a full list of proposed features (and known issues).
154 |
155 |
156 |
157 |
158 | ## Contributing
159 |
160 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
161 |
162 | If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
163 |
164 | Be sure to read the [contribution guidelines](CONTRIBUTING.md) before contributing.
165 |
166 | Follow below steps to make your contribution count.
167 |
168 | ## 🖱️ How to Contribute
169 |
170 | If you think that you can add a new feature or want to fix a bug, we invite you to contribute to Stock-Watchlist and make this project better. To start contributing, follow the below instructions:
171 |
172 | 1. Create a folder at your desire location (usually at your desktop).
173 |
174 | 2. Open Git Bash Here
175 |
176 |
177 | 3. [Fork](https://github.com/PEC-CSS/Stock-Watchlist) the project. Click on the icon in the top right to get started.
178 |
179 | 4. Clone your forked repository of project.
180 |
181 | ```bash
182 | git clone https://github.com/PEC-CSS/Stock-Watchlist.git
183 | ```
184 |
185 | 5. Navigate to the project directory.
186 |
187 | ```bash
188 | cd Stock-Watchlist
189 | ```
190 |
191 | 6. Add a reference(remote) to the original repository.
192 |
193 | ```bash
194 | git remote add upstream https://github.com/PEC-CSS/Stock-Watchlist.git
195 | ```
196 |
197 | 7. Check the remotes for this repository.
198 |
199 | ```bash
200 | git remote -v
201 | ```
202 |
203 | 8. Always take a pull from the upstream repository to your main branch to keep it updated as per the main project repository.
204 |
205 | ```bash
206 | git pull upstream main
207 | ```
208 |
209 | 9. Create a new branch(prefer a branch name that relates to your assigned issue).
210 |
211 | ```bash
212 | git checkout -b
213 | ```
214 |
215 | 10. Perform your desired changes to the code base.
216 |
217 | 11. Check your changes.
218 |
219 | ```bash
220 | git status
221 | ```
222 |
223 | ```bash
224 | git diff
225 | ```
226 |
227 | 12. Stage your changes.
228 |
229 | ```bash
230 | git add . <\files_that_you_made_changes>
231 | ```
232 |
233 | 13. Commit your changes.
234 |
235 | ```bash
236 | git commit -m "Commit Message"
237 | ```
238 |
239 | 14. Push the committed changes in your feature branch to your remote repository.
240 |
241 | ```bash
242 | git push -u origin
243 | ```
244 |
245 | 15. To create a pull request, click on `compare and pull requests`.
246 |
247 | 16. Add an appropriate title and description to your PR explaining your changes.
248 |
249 | 17. Click on `Create pull request`.
250 |
251 | Congratulations🎉, you have made a PR to the Stock-Watchlist.
252 | Wait for your submission to be accepted and your PR to be merged by a maintainer.
253 |
254 | ## 🫴 How to Do Your First Pull Request?
255 | ***(We are providing some Resource from where you can Learn)***
256 |
257 | 1. [Learn from Video](https://www.youtube.com/watch?v=nkuYH40cjo4)
258 | 2. [Open Source Guide](https://opensource.guide/how-to-contribute/)
259 |
260 | ## Code of Conduct
261 |
262 | - [Code of Conduct](CODE_OF_CONDUCT.md)
263 |
264 | ## 🙏🏽 Support
265 |
266 | This project needs a star️ from you. Don't forget to leave a star✨
267 | Follow my Github for content
268 |
269 |
270 |
271 | © PEC ACM CSS
272 |
273 |
274 |
275 | ## License
276 |
277 | Distributed under the MIT License. See [LICENSE](LICENSE) for more information.
278 |
279 |
280 | ## Contact
281 |
282 | [Rahul Sharma](https://rahulsharma.vercel.app/) - acmcss@pec.edu.in - rahul2702sharma@gmail.com
283 |
284 | Project Link: [https://github.com/PEC-CSS/Stock-Watchlist](https://github.com/PEC-CSS/Stock-Watchlist)
285 |
286 |
287 | ## Acknowledgments
288 |
289 | Use this space to list resources you find helpful and would like to give credit to. I've included a few of my favorites to kick things off!
290 |
291 | * [React Native docs](https://reactnative.dev/docs/getting-started)
292 | * [Expo Docs](https://docs.expo.dev/)
293 | * [Messari API](https://messari.io/api)
294 | * [Let's build Tinder 2.0 with REACT NATIVE! (Messaging, ContextAPI, Tailwind, Google Auth, Firebase)](https://www.youtube.com/watch?v=qJaFIGjyRms)
295 | * [Img Shields](https://shields.io)
296 | * [othneildrew / Best-README-Template](https://github.com/othneildrew/Best-README-Template)
297 |
298 | (back to top )
299 |
300 |
301 |
302 |
303 |
304 |
305 | [contributors-shield]: https://img.shields.io:/github/contributors/PEC-CSS/Stock-Watchlist?style=for-the-badge
306 | [contributors-url]: https://github.com/PEC-CSS/Stock-Watchlist/graphs/contributors
307 | [forks-shield]: https://img.shields.io/github/forks/PEC-CSS/Stock-Watchlist?style=for-the-badge
308 | [forks-url]: https://github.com/PEC-CSS/Stock-Watchlist/network/members
309 | [stars-shield]: https://img.shields.io/github/stars/PEC-CSS/Stock-Watchlist?style=for-the-badge
310 | [stars-url]: https://github.com/PEC-CSS/Stock-Watchlist/stargazers
311 | [issues-shield]: https://img.shields.io/github/issues/PEC-CSS/Stock-Watchlist?style=for-the-badge
312 | [issues-url]: https://github.com/PEC-CSS/Stock-Watchlist/issues
313 | [license-shield]: https://img.shields.io/github/license/PEC-CSS/Stock-Watchlist?style=for-the-badge
314 | [license-url]: https://github.com/PEC-CSS/Stock-Watchlist/blob/master/LICENSE.txt
315 | [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
316 | [linkedin-url]: https://www.linkedin.com/in/rahul5430/
317 | [product-screenshot-loginScreen]: assets/loginScreen.gif
318 | [product-screenshot-stockScreenAndWatchlist]: assets/stockScreenAndWatchlist.gif
319 | [product-screenshot-aboutAndProfileScreen]: assets/aboutAndProfileScreen.gif
320 | [product-screenshot-searchScreen]: assets/searchScreen.gif
321 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "Stock Watchlist",
4 | "slug": "stock-watchlist",
5 | "scheme": "stock-watchlist",
6 | "version": "1.0.0",
7 | "orientation": "portrait",
8 | "icon": "./assets/icons/android/playstore-icon.png",
9 | "androidStatusBar": {
10 | "barStyle": "dark-content",
11 | "backgroundColor": "#00000000"
12 | },
13 | "splash": {
14 | "image": "./assets/splash.png",
15 | "resizeMode": "contain",
16 | "backgroundColor": "#ffffff"
17 | },
18 | "updates": {
19 | "fallbackToCacheTimeout": 0
20 | },
21 | "assetBundlePatterns": ["**/*"],
22 | "ios": {
23 | "supportsTablet": true,
24 | "bundleIdentifier": "com.stockwatchlist",
25 | "config": {
26 | // "googleSignIn": {
27 | // "reservedClientId": "com.googleusercontent.apps.316148951749-8u2uof18venstiufjg0q4uv0hnp1i5lh"
28 | // }
29 | }
30 | },
31 | "android": {
32 | "adaptiveIcon": {
33 | "foregroundImage": "./assets/icons/android/playstore-icon.png",
34 | "backgroundColor": "#FFFFFF"
35 | },
36 | "config": {
37 | // "googleSignIn": {
38 | // "apiKey": "AIzaSyBlaYemjd3RU6WzFNFKKga1hMymcDRCyB4",
39 | // "certificateHash": "53C960C9BAD9A5C8FE338EED1BD26F80099F55C1"
40 | // }
41 | },
42 | "splash": {
43 | "backgroundColor": "#FFFFFF",
44 | "image": "./assets/splash.png",
45 | "resizeMode": "contain"
46 | },
47 | "softwareKeyboardLayoutMode": "pan",
48 | "package": "com.stockwatchlist"
49 | },
50 | "web": {
51 | "favicon": "./assets/favicon.png"
52 | },
53 | "extra": {
54 | "eas": {
55 | "projectId": "fe45b032-6d12-4348-b3f2-dfeb5be7b0e4"
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/assets/aboutAndProfileScreen.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/aboutAndProfileScreen.gif
--------------------------------------------------------------------------------
/assets/accurate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/accurate.png
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/adfree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/adfree.png
--------------------------------------------------------------------------------
/assets/depositphotos_29671351-stock-photo-searching.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/depositphotos_29671351-stock-photo-searching.jpg
--------------------------------------------------------------------------------
/assets/easytouse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/easytouse.png
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/favicon.png
--------------------------------------------------------------------------------
/assets/fonts/Overpass-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/fonts/Overpass-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Overpass-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/fonts/Overpass-ExtraBold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Overpass-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/fonts/Overpass-Light.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/fonts/Ubuntu-Medium.ttf
--------------------------------------------------------------------------------
/assets/getstarted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/getstarted.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icon.png
--------------------------------------------------------------------------------
/assets/icons/android/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/ic_launcher-web.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/assets/icons/android/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/assets/icons/android/playstore-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/android/playstore-icon.png
--------------------------------------------------------------------------------
/assets/icons/android/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #f76c60
4 |
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images":[
3 | {
4 | "idiom":"iphone",
5 | "size":"20x20",
6 | "scale":"2x",
7 | "filename":"Icon-App-20x20@2x.png"
8 | },
9 | {
10 | "idiom":"iphone",
11 | "size":"20x20",
12 | "scale":"3x",
13 | "filename":"Icon-App-20x20@3x.png"
14 | },
15 | {
16 | "idiom":"iphone",
17 | "size":"29x29",
18 | "scale":"1x",
19 | "filename":"Icon-App-29x29@1x.png"
20 | },
21 | {
22 | "idiom":"iphone",
23 | "size":"29x29",
24 | "scale":"2x",
25 | "filename":"Icon-App-29x29@2x.png"
26 | },
27 | {
28 | "idiom":"iphone",
29 | "size":"29x29",
30 | "scale":"3x",
31 | "filename":"Icon-App-29x29@3x.png"
32 | },
33 | {
34 | "idiom":"iphone",
35 | "size":"40x40",
36 | "scale":"2x",
37 | "filename":"Icon-App-40x40@2x.png"
38 | },
39 | {
40 | "idiom":"iphone",
41 | "size":"40x40",
42 | "scale":"3x",
43 | "filename":"Icon-App-40x40@3x.png"
44 | },
45 | {
46 | "idiom":"iphone",
47 | "size":"60x60",
48 | "scale":"2x",
49 | "filename":"Icon-App-60x60@2x.png"
50 | },
51 | {
52 | "idiom":"iphone",
53 | "size":"60x60",
54 | "scale":"3x",
55 | "filename":"Icon-App-60x60@3x.png"
56 | },
57 | {
58 | "idiom":"iphone",
59 | "size":"76x76",
60 | "scale":"2x",
61 | "filename":"Icon-App-76x76@2x.png"
62 | },
63 | {
64 | "idiom":"ipad",
65 | "size":"20x20",
66 | "scale":"1x",
67 | "filename":"Icon-App-20x20@1x.png"
68 | },
69 | {
70 | "idiom":"ipad",
71 | "size":"20x20",
72 | "scale":"2x",
73 | "filename":"Icon-App-20x20@2x.png"
74 | },
75 | {
76 | "idiom":"ipad",
77 | "size":"29x29",
78 | "scale":"1x",
79 | "filename":"Icon-App-29x29@1x.png"
80 | },
81 | {
82 | "idiom":"ipad",
83 | "size":"29x29",
84 | "scale":"2x",
85 | "filename":"Icon-App-29x29@2x.png"
86 | },
87 | {
88 | "idiom":"ipad",
89 | "size":"40x40",
90 | "scale":"1x",
91 | "filename":"Icon-App-40x40@1x.png"
92 | },
93 | {
94 | "idiom":"ipad",
95 | "size":"40x40",
96 | "scale":"2x",
97 | "filename":"Icon-App-40x40@2x.png"
98 | },
99 | {
100 | "idiom":"ipad",
101 | "size":"76x76",
102 | "scale":"1x",
103 | "filename":"Icon-App-76x76@1x.png"
104 | },
105 | {
106 | "idiom":"ipad",
107 | "size":"76x76",
108 | "scale":"2x",
109 | "filename":"Icon-App-76x76@2x.png"
110 | },
111 | {
112 | "idiom":"ipad",
113 | "size":"83.5x83.5",
114 | "scale":"2x",
115 | "filename":"Icon-App-83.5x83.5@2x.png"
116 | },
117 | {
118 | "size" : "1024x1024",
119 | "idiom" : "ios-marketing",
120 | "scale" : "1x",
121 | "filename" : "ItunesArtwork@2x.png"
122 | }
123 | ],
124 | "info":{
125 | "version":1,
126 | "author":"easyappicon"
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/assets/icons/ios/AppIcon.appiconset/ItunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/AppIcon.appiconset/ItunesArtwork@2x.png
--------------------------------------------------------------------------------
/assets/icons/ios/iTunesArtwork@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/iTunesArtwork@1x.png
--------------------------------------------------------------------------------
/assets/icons/ios/iTunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/iTunesArtwork@2x.png
--------------------------------------------------------------------------------
/assets/icons/ios/iTunesArtwork@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/icons/ios/iTunesArtwork@3x.png
--------------------------------------------------------------------------------
/assets/loginScreen.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/loginScreen.gif
--------------------------------------------------------------------------------
/assets/logo-circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/logo-circle.png
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/logo.png
--------------------------------------------------------------------------------
/assets/search-result-not-found-2130361-1800925.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/search-result-not-found-2130361-1800925.png
--------------------------------------------------------------------------------
/assets/searchScreen.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/searchScreen.gif
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/splash.png
--------------------------------------------------------------------------------
/assets/stock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/stock.png
--------------------------------------------------------------------------------
/assets/stockScreenAndWatchlist.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/stockScreenAndWatchlist.gif
--------------------------------------------------------------------------------
/assets/welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/assets/welcome.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | plugins: [
6 | ["module:react-native-dotenv"]
7 | ],
8 | env: {
9 | production: {
10 | plugins: ['react-native-paper/babel'],
11 | },
12 | },
13 | };
14 | };
15 |
--------------------------------------------------------------------------------
/components/Listcard.js:
--------------------------------------------------------------------------------
1 | import { FontAwesome } from '@expo/vector-icons';
2 | import React from 'react';
3 | import {
4 | View,
5 | StyleSheet,
6 | Image,
7 | Text,
8 | TouchableHighlight,
9 | } from 'react-native';
10 |
11 | const Listcard = ({
12 | title,
13 | subTitle,
14 | image,
15 | IconComponent,
16 | onPress,
17 | price,
18 | changeRate,
19 | match,
20 | updateWatchlistData,
21 | }) => {
22 | const colorfun = () => {
23 | if (changeRate > 0) {
24 | return '#00E59F';
25 | }
26 | return '#FC7682';
27 | };
28 |
29 | return (
30 |
31 |
32 | {IconComponent}
33 | {image && (
34 |
35 | )}
36 |
37 |
38 | {title}
39 |
40 | {subTitle && (
41 |
42 | {subTitle}
43 |
44 | )}
45 |
46 |
47 |
48 | ${price}
49 |
50 | {subTitle && (
51 |
63 |
64 | {changeRate}%
65 |
66 |
67 | )}
68 |
69 | updateWatchlistData(match, title)}
74 | />
75 |
76 |
77 | );
78 | };
79 |
80 | const styles = StyleSheet.create({
81 | container: {
82 | alignItems: 'center',
83 | flexDirection: 'row',
84 | padding: 15,
85 | backgroundColor: '#f0f8ff',
86 | borderBottomWidth: 1,
87 | borderBottomColor: 'white',
88 | },
89 | detailsContainer: {
90 | flex: 1,
91 | marginLeft: 10,
92 | justifyContent: 'center',
93 | },
94 | detailsContainer: {
95 | flex: 1,
96 | marginLeft: 10,
97 | justifyContent: 'flex-end',
98 | },
99 | leftdetailsContainer: {
100 | alignSelf: 'flex-start',
101 | marginTop: 2,
102 | marginRight: 10,
103 | },
104 | image: {
105 | width: 50,
106 | height: 50,
107 | borderRadius: 35,
108 | },
109 | rate: {
110 | textAlign: 'center',
111 | fontWeight: '400',
112 | color: 'white',
113 | },
114 | subTitle: {
115 | color: '#6e6969',
116 | },
117 | title: {
118 | fontWeight: '600',
119 | fontSize: 16,
120 | },
121 | });
122 |
123 | export default Listcard;
124 |
--------------------------------------------------------------------------------
/components/card/Card.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Image, Text, View, StyleSheet, TouchableOpacity } from 'react-native';
3 |
4 | export const Card = ({ name, symbol, image, price, changeRate }) => {
5 | const growth = changeRate < 0 ? '↓ ' : '↑ ';
6 | return (
7 |
8 |
9 |
10 | {symbol}
11 | {name}
12 |
13 |
14 | {'$' + price}
15 |
21 | {growth + Math.abs(changeRate) + '%'}
22 |
23 |
24 |
25 | );
26 | };
27 |
28 | const styles = StyleSheet.create({
29 | containerStyle: {
30 | flexDirection: 'row',
31 | padding: 10,
32 | marginHorizontal: 2,
33 | marginVertical: 5,
34 | borderRadius: 30,
35 | elevation: 5,
36 | shadowColor: 'black',
37 | shadowOffset: {
38 | width: 0,
39 | height: 1,
40 | },
41 | shadowOpacity: 0.8,
42 | shadowRadius: 1,
43 | },
44 | imageStyle: {
45 | height: 70,
46 | width: 70,
47 | flex: 1,
48 | },
49 | textStyle: {
50 | justifyContent: 'center',
51 | alignContent: 'center',
52 | marginHorizontal: 10,
53 | flex: 3,
54 | },
55 | symbolStyle: {
56 | fontSize: 30,
57 | fontWeight: 'bold',
58 | },
59 | nameStyle: {
60 | fontSize: 18,
61 | },
62 | numStyle: {
63 | justifyContent: 'center',
64 | alignContent: 'flex-end',
65 | alignItems: 'center',
66 | marginHorizontal: 5,
67 | flex: 1.1,
68 | },
69 | priceStyle: {
70 | fontWeight: 'bold',
71 | marginVertical: 5,
72 | fontSize: 15,
73 | },
74 | changeStyle: {
75 | color: 'white',
76 | fontWeight: 'bold',
77 | padding: 2,
78 | borderRadius: 5,
79 | marginVertical: 5,
80 | },
81 | });
82 |
--------------------------------------------------------------------------------
/components/card/index.jsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PEC-CSS/Stock-Watchlist/cc30ccdca95b02808259840d5fc93b79b8840b09/components/card/index.jsx
--------------------------------------------------------------------------------
/components/header/headerLoginPage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StyleSheet, View, Text, TouchableOpacity, Image } from 'react-native';
3 | import { useFonts } from 'expo-font';
4 | import Apploading from 'expo-app-loading';
5 |
6 | export default function HeaderLogin() {
7 | let [fontsLoaded, error] = useFonts({
8 | Overpass: require('../../assets/fonts/Overpass-Bold.ttf'),
9 | });
10 |
11 | if (!fontsLoaded) {
12 | return ;
13 | }
14 |
15 | return (
16 |
17 |
18 |
22 |
23 | STOCK WATCHLIST
24 |
25 | );
26 | }
27 |
28 | const styles = StyleSheet.create({
29 | header: {
30 | height: 50,
31 | backgroundColor: '#11468f',
32 | display: 'flex',
33 | flexDirection: 'row',
34 | alignItems: 'center',
35 | // paddingTop: 5,
36 | },
37 | headerContent: {
38 | color: 'white',
39 | fontFamily: 'Overpass',
40 | fontSize: 25,
41 | // position: 'absolute',
42 | // top: 2,
43 | // left: '14%',
44 | },
45 | logo: {
46 | height: 40,
47 | width: 40,
48 | marginLeft: 9,
49 | marginRight: 7,
50 | // margin: '0 auto',
51 | // borderRadius: 20,
52 | },
53 | });
54 |
--------------------------------------------------------------------------------
/components/navbar/index.jsx:
--------------------------------------------------------------------------------
1 | // watchlist and news
2 |
--------------------------------------------------------------------------------
/components/navbar/navbarBottom.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
3 | import { Feather, FontAwesome } from '@expo/vector-icons';
4 | import { useNavigation } from '@react-navigation/core';
5 |
6 | const Search = ({ data }) => {
7 | const navigation = useNavigation();
8 |
9 | return (
10 |
11 | {
13 | navigation.navigate('Stocks', { clicked: true });
14 | }}
15 | >
16 |
17 |
18 | Stocks
19 |
20 |
21 | {
23 | navigation.navigate('Search', {
24 | clicked: true,
25 | data: data,
26 | });
27 | }}
28 | >
29 |
30 | {
35 | // navigation.navigate('Search', { clicked: true });
36 | // }}
37 | />
38 | Search
39 |
40 |
41 | {
43 | navigation.navigate('Profile', { clicked: true });
44 | }}
45 | >
46 |
47 |
48 | Profile
49 |
50 |
51 |
52 | );
53 | };
54 |
55 | export default function navbarBottom(props) {
56 | return ;
57 | }
58 |
59 | const styles = StyleSheet.create({
60 | container: {
61 | backgroundColor: '#002D62',
62 | position: 'absolute',
63 | height: 53,
64 | width: '100%',
65 | bottom: 0,
66 | flex: 1,
67 | flexDirection: 'row',
68 | alignItems: 'center',
69 | },
70 | text: {
71 | color: 'white',
72 | fontSize: 18,
73 | },
74 | home: {
75 | alignItems: 'center',
76 | paddingLeft: 25,
77 | paddingRight: 40,
78 | // borderRightWidth: 1,
79 | // borderRightColor: 'white',
80 | },
81 | search: {
82 | alignItems: 'center',
83 | paddingLeft: 40,
84 | paddingRight: 40,
85 | // borderRightWidth: 1,
86 | // borderRightColor: 'white',
87 | },
88 | profile: {
89 | alignItems: 'center',
90 | paddingLeft: 30,
91 | paddingRight: 30,
92 | },
93 | });
94 |
--------------------------------------------------------------------------------
/components/profile/index.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Image, StyleSheet, Text, View, Dimensions } from 'react-native';
3 |
4 | const window = Dimensions.get('window');
5 |
6 | const UserComponent = ({ user }) => {
7 | return (
8 |
9 |
10 | {/* */}
14 |
15 | {user.providerData[0].displayName}
16 | {/* Name: {user.providerData[0].displayName} */}
17 |
18 |
19 | {user.providerData[0].email}
20 | {/* Email: {user.providerData[0].email} */}
21 |
22 | {user.providerData[0].phoneNumber && (
23 |
24 | Phone Number: {user.providerData[0].phoneNumber}
25 |
26 | )}
27 |
28 |
32 |
33 | );
34 | };
35 |
36 | const styles = StyleSheet.create({
37 | container: {
38 | // justifyContent: 'center',
39 | alignItems: 'center',
40 | // backgroundColor: '#9DD6EB',
41 | backgroundColor: '#ffffff',
42 | borderTopRightRadius: 20,
43 | borderTopLeftRadius: 20,
44 | marginTop: -20,
45 | paddingTop: 20,
46 | overflow: 'hidden',
47 | flex: 1,
48 | alignSelf: 'stretch',
49 | zIndex: 5,
50 | },
51 | image: {
52 | width: 55,
53 | height: 55,
54 | borderRadius: 50,
55 | padding: 5,
56 | // marginTop: -45,
57 | zIndex: 10,
58 | position: 'absolute',
59 | top: 126.5,
60 | left: window.width / 2 - 27.5,
61 | },
62 | image1: {
63 | width: 55,
64 | height: 55,
65 | borderRadius: 50,
66 | padding: 5,
67 | marginTop: -47.5,
68 | zIndex: 10,
69 | },
70 | name: {
71 | paddingTop: 10,
72 | fontSize: 25,
73 | fontWeight: 'bold',
74 | },
75 | text: {
76 | paddingTop: 10,
77 | fontSize: 15,
78 | fontWeight: 'bold',
79 | },
80 | });
81 |
82 | export default UserComponent;
83 |
--------------------------------------------------------------------------------
/components/search/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Keyboard, StyleSheet, TextInput, View } from 'react-native';
3 | import { Feather, Entypo } from '@expo/vector-icons';
4 |
5 | const SearchBar = (props) => {
6 | return (
7 |
8 | {/* Search Icon */}
9 |
15 | {/* Input Field */}
16 | {
22 | props.setClicked(true);
23 | }}
24 | />
25 | {/* cross Icon, depending on whether the search bar is clicked or not */}
26 | {
32 | Keyboard.dismiss();
33 | props.setSearchPhrase('');
34 | }}
35 | />
36 |
37 | );
38 | };
39 |
40 | const styles = StyleSheet.create({
41 | container: {
42 | padding: 10,
43 | flexDirection: 'row',
44 | width: '95%',
45 | backgroundColor: '#d9dbda',
46 | borderRadius: 15,
47 | alignItems: 'center',
48 | justifyContent: 'space-evenly',
49 | },
50 | input: {
51 | fontSize: 22,
52 | paddingLeft: 20,
53 | width: '90%',
54 | },
55 | });
56 |
57 | export default SearchBar;
58 |
--------------------------------------------------------------------------------
/components/search/suggestion/index.jsx:
--------------------------------------------------------------------------------
1 | import { FontAwesome } from '@expo/vector-icons';
2 | import React from 'react';
3 | import {
4 | Image,
5 | RefreshControl,
6 | SafeAreaView,
7 | ScrollView,
8 | StyleSheet,
9 | Text,
10 | View,
11 | } from 'react-native';
12 |
13 | // definition of the Item, which will be rendered in the FlatList
14 | const Item = ({ item, match, updateWatchlistData }) => {
15 | const image = `https://messari.io/asset-images/${item.id}/128.png`;
16 | const price =
17 | item.metrics.market_data.price_usd < 1.01
18 | ? Math.round(item.metrics.market_data.price_usd * 1000000) / 1000000
19 | : Math.round(item.metrics.market_data.price_usd * 100) / 100;
20 | const changeRate =
21 | Math.round(
22 | item.metrics.market_data.percent_change_usd_last_24_hours * 100
23 | ) / 100;
24 |
25 | return (
26 |
27 |
31 |
32 |
33 | {item.name}
34 |
35 |
36 | {item.symbol}
37 |
38 |
39 |
40 |
41 | ${price}
42 |
43 | 0 ? '#00E59F' : '#FC7682',
46 | borderRadius: 10,
47 | paddingVertical: 6,
48 | position: 'absolute',
49 | marginTop: 20,
50 | right: 0,
51 | width: 68,
52 | textAlign: 'center',
53 | }}
54 | >
55 |
56 | {changeRate}%
57 |
58 |
59 |
60 | updateWatchlistData(match, item.symbol)}
65 | />
66 |
67 | );
68 | };
69 |
70 | const NoItemFound = ({ searchPhrase }) => {
71 | return (
72 |
73 |
77 |
78 | Sorry, No results found for "{searchPhrase}"
79 |
80 |
81 | );
82 | };
83 |
84 | const List = (props) => {
85 | const filterData = (data) => {
86 | return data.filter(
87 | (item) =>
88 | props.searchPhrase === '' ||
89 | item.name
90 | .toUpperCase()
91 | .includes(
92 | props.searchPhrase
93 | .toUpperCase()
94 | .trim()
95 | .replace(/\s/g, '')
96 | ) ||
97 | item.symbol
98 | .toUpperCase()
99 | .includes(
100 | props.searchPhrase
101 | .toUpperCase()
102 | .trim()
103 | .replace(/\s/g, '')
104 | )
105 | );
106 | };
107 |
108 | return (
109 |
110 |
116 | }
117 | >
118 | {
120 | props.setClicked(false);
121 | }}
122 | >
123 | {!filterData(props.data).length ? (
124 |
125 | ) : (
126 | filterData(props.data).map((item) => (
127 |
133 | ))
134 | )}
135 |
136 |
137 |
138 | );
139 | };
140 |
141 | export default List;
142 |
143 | const styles = StyleSheet.create({
144 | list__container: {
145 | margin: 10,
146 | height: '85%',
147 | width: '100%',
148 | },
149 | item: {
150 | margin: 30,
151 | borderBottomWidth: 2,
152 | borderBottomColor: 'lightgrey',
153 | },
154 | title: {
155 | fontSize: 20,
156 | fontWeight: 'bold',
157 | marginBottom: 5,
158 | fontStyle: 'italic',
159 | },
160 | image: {
161 | alignSelf: 'center',
162 | resizeMode: 'center',
163 | },
164 | imageContainer: {
165 | justifyContent: 'center',
166 | alignItems: 'center',
167 | flex: 1,
168 | flexDirection: 'column',
169 | },
170 | notFoundText: {
171 | textAlign: 'center',
172 | },
173 | container: {
174 | alignItems: 'center',
175 | flexDirection: 'row',
176 | padding: 15,
177 | backgroundColor: '#f0f8ff',
178 | borderBottomWidth: 1,
179 | borderBottomColor: 'white',
180 | },
181 | detailsContainer: {
182 | flex: 1,
183 | marginLeft: 10,
184 | justifyContent: 'flex-end',
185 | },
186 | leftdetailsContainer: {
187 | alignSelf: 'flex-start',
188 | marginTop: 2,
189 | marginRight: 10,
190 | },
191 | rate: {
192 | textAlign: 'center',
193 | fontWeight: '400',
194 | color: 'white',
195 | },
196 | subTitle: {
197 | color: '#6e6969',
198 | },
199 | price: {
200 | fontWeight: '600',
201 | fontSize: 16,
202 | },
203 | });
204 |
--------------------------------------------------------------------------------
/components/watchlist/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useCallback } from 'react';
2 | import {
3 | ActivityIndicator,
4 | Image,
5 | RefreshControl,
6 | ScrollView,
7 | StyleSheet,
8 | View,
9 | Text,
10 | } from 'react-native';
11 | import {
12 | doc,
13 | getDoc,
14 | setDoc,
15 | updateDoc,
16 | arrayUnion,
17 | arrayRemove,
18 | } from 'firebase/firestore';
19 | import Toast from 'react-native-root-toast';
20 | import { X_MESSARI_API_KEY } from '@env';
21 | import WatchListItem from './item';
22 | import useAuth from '../../hooks/useAuth';
23 | import { db } from '../../firebase';
24 |
25 | const NoWatchlistFound = () => {
26 | return (
27 |
28 |
32 | You seem to have no watchlists
33 | Create one to start tracking your favourite assets
34 |
35 | );
36 | };
37 |
38 | const WatchList = () => {
39 | const { user } = useAuth();
40 | const docRef = doc(db, 'users', user.uid);
41 | const [refreshing, setRefreshing] = useState(false);
42 | const [cryptoData, setCrytpoData] = useState({ data: [] });
43 | const [watchlistData, setWatchlistData] = useState([]);
44 | getDoc(docRef).then((docSnap) => {
45 | if (docSnap.exists()) {
46 | console.log('Document data:', docSnap.data());
47 | if (!watchlistData) {
48 | setWatchlistData(docSnap.data().watchlist);
49 | }
50 | } else {
51 | console.log('No such document!');
52 | setDoc(docRef, {
53 | name: user.providerData[0].displayName,
54 | email: user.providerData[0].email,
55 | watchlist: [],
56 | });
57 | }
58 | });
59 | const a = 10;
60 |
61 | const updateWatchlistData = (match, symbol) => {
62 | console.log(match, symbol);
63 | const toastOptions = {};
64 | if (match) {
65 | // symbol present in watchlist. remove it
66 | let toast = Toast.show(
67 | `Removing ${symbol} from watchlist...`,
68 | toastOptions
69 | );
70 | updateDoc(docRef, {
71 | watchlist: arrayRemove(symbol),
72 | });
73 | Toast.hide(toast);
74 | Toast.show(`Removed ${symbol} from watchlist...`, toastOptions);
75 | } else {
76 | // symbol not present in watchlist. add it
77 | let toast = Toast.show(
78 | `Adding ${symbol} to watchlist...`,
79 | toastOptions
80 | );
81 | updateDoc(docRef, {
82 | watchlist: arrayUnion(symbol),
83 | });
84 | Toast.hide(toast);
85 | Toast.show(`Added ${symbol} to watchlist...`, toastOptions);
86 | }
87 | getDoc(docRef).then((docSnap) => {
88 | setWatchlistData(docSnap.data().watchlist);
89 | });
90 | };
91 |
92 | useEffect(() => {
93 | fetch(
94 | 'https://data.messari.io/api/v2/assets?fields=id,symbol,name,metrics/market_data',
95 | {
96 | method: 'GET',
97 | headers: { 'x-messari-api-key': X_MESSARI_API_KEY },
98 | }
99 | )
100 | .then((response) => response.json())
101 | .then((jsonResponse) => setCrytpoData(jsonResponse))
102 | .catch((error) => console.log(error));
103 | // .finally(() => console.log(cryptoData));
104 | getDoc(docRef).then((docSnap) => {
105 | setWatchlistData(docSnap.data().watchlist);
106 | });
107 | }, [a]);
108 |
109 | const onRefresh = useCallback(() => {
110 | setRefreshing(true);
111 | fetch(
112 | 'https://data.messari.io/api/v2/assets?fields=id,symbol,name,metrics/market_data',
113 | {
114 | method: 'GET',
115 | headers: { 'x-messari-api-key': X_MESSARI_API_KEY },
116 | }
117 | )
118 | .then((response) => response.json())
119 | .then((jsonResponse) => setCrytpoData(jsonResponse))
120 | .then(() => setRefreshing(false))
121 | .catch((error) => console.log(error));
122 | // .finally(() => console.log(cryptoData));
123 | getDoc(docRef).then((docSnap) => {
124 | setWatchlistData(docSnap.data().watchlist);
125 | });
126 | }, []);
127 |
128 | const filterData = (data, cryptoData) => {
129 | return cryptoData.filter((item) =>
130 | data.find((symbol) => symbol === item.symbol)
131 | );
132 | };
133 |
134 | return (
135 |
136 |
143 | }
144 | >
145 | {!cryptoData.data.length ? (
146 |
151 | ) : !watchlistData.length ? (
152 |
153 | ) : (
154 | filterData(watchlistData, cryptoData.data).map((item) => (
155 |
161 | ))
162 | )}
163 |
164 |
165 | );
166 | };
167 |
168 | const styles = StyleSheet.create({
169 | noWatchlistFoundContainer: {
170 | flex: 1,
171 | justifyContent: 'center',
172 | alignItems: 'center',
173 | },
174 | image: {
175 | height: 200,
176 | width: 200,
177 | },
178 | });
179 |
180 | export default WatchList;
181 |
--------------------------------------------------------------------------------
/components/watchlist/item/index.jsx:
--------------------------------------------------------------------------------
1 | import { FontAwesome } from '@expo/vector-icons';
2 | import React from 'react';
3 | import { Image, StyleSheet, Text, View } from 'react-native';
4 |
5 | const WatchListItem = ({ item, match, updateWatchlistData }) => {
6 | const image = `https://messari.io/asset-images/${item.id}/128.png`;
7 | const price =
8 | item.metrics.market_data.price_usd < 1.01
9 | ? Math.round(item.metrics.market_data.price_usd * 1000000) / 1000000
10 | : Math.round(item.metrics.market_data.price_usd * 100) / 100;
11 | const changeRate =
12 | Math.round(
13 | item.metrics.market_data.percent_change_usd_last_24_hours * 100
14 | ) / 100;
15 |
16 | return (
17 |
18 |
22 |
23 |
24 | {item.name}
25 |
26 |
27 | {item.symbol}
28 |
29 |
30 |
31 |
32 | ${price}
33 |
34 | 0 ? '#00E59F' : '#FC7682',
37 | borderRadius: 10,
38 | paddingVertical: 6,
39 | position: 'absolute',
40 | marginTop: 20,
41 | right: 0,
42 | width: 68,
43 | textAlign: 'center',
44 | }}
45 | >
46 |
47 | {changeRate}%
48 |
49 |
50 |
51 | updateWatchlistData(match, item.symbol)}
56 | />
57 |
58 | );
59 | };
60 |
61 | const styles = StyleSheet.create({
62 | container: {
63 | alignItems: 'center',
64 | flexDirection: 'row',
65 | padding: 15,
66 | backgroundColor: '#f0f8ff',
67 | borderBottomWidth: 1,
68 | borderBottomColor: 'white',
69 | },
70 | detailsContainer: {
71 | flex: 1,
72 | marginLeft: 10,
73 | justifyContent: 'flex-end',
74 | },
75 | leftdetailsContainer: {
76 | alignSelf: 'flex-start',
77 | marginTop: 2,
78 | marginRight: 10,
79 | },
80 | rate: {
81 | textAlign: 'center',
82 | fontWeight: '400',
83 | color: 'white',
84 | },
85 | title: {
86 | fontSize: 20,
87 | fontWeight: 'bold',
88 | marginBottom: 5,
89 | fontStyle: 'italic',
90 | },
91 | subTitle: {
92 | color: '#6e6969',
93 | },
94 | price: {
95 | fontWeight: '600',
96 | fontSize: 16,
97 | },
98 | });
99 |
100 | export default WatchListItem;
101 |
--------------------------------------------------------------------------------
/eas.json:
--------------------------------------------------------------------------------
1 | {
2 | "cli": {
3 | "version": ">= 0.47.0"
4 | },
5 | "build": {
6 | "development": {
7 | "developmentClient": true,
8 | "distribution": "internal",
9 | "env": {
10 | "API_KEY": "AIzaSyDyjTYFGvcM7PM9D0O_IzEYG5bm2kgoGBY",
11 | "AUTH_DOMAIN": "stock-watchlist-pec.firebaseapp.com",
12 | "PROJECT_ID": "stock-watchlist-pec",
13 | "STORAGE_BUCKET": "stock-watchlist-pec.appspot.com",
14 | "MESSAGING_SENDER_ID": "316148951749",
15 | "APP_ID": "1:316148951749:web:3fed8a95e649e78d605eac",
16 | "MEASUREMENT_ID": "G-BQMYPTRNNX",
17 | "ANDROID_CLIENT_ID": "316148951749-eg5o8km0k13u03b8r32phi6v6f8vr3dn.apps.googleusercontent.com",
18 | "IOS_CLIENT_ID": "316148951749-f92vbdc04mughtfsb8feimdr950aedc1.apps.googleusercontent.com",
19 | "ANDROID_STANDALONE_APP_CLIENT_ID": "316148951749-lj3gsji24t5tb07eqjen9ov3jrpvgcjp.apps.googleusercontent.com",
20 | "IOS_STANDALONE_APP_CLIENT_ID": "316148951749-8u2uof18venstiufjg0q4uv0hnp1i5lh.apps.googleusercontent.com",
21 | "EXPO_CLIENT_ID": "316148951749-qhh8q0ebn8dd5b0hfmlsmokom2bqrlpb.apps.googleusercontent.com",
22 | "X_MESSARI_API_KEY": "9f3cc221-44ec-460a-bf7a-8576d8e6dcf9",
23 | "PROXY": "false"
24 | }
25 | },
26 | "preview": {
27 | "distribution": "internal",
28 | "env": {
29 | "API_KEY": "AIzaSyDyjTYFGvcM7PM9D0O_IzEYG5bm2kgoGBY",
30 | "AUTH_DOMAIN": "stock-watchlist-pec.firebaseapp.com",
31 | "PROJECT_ID": "stock-watchlist-pec",
32 | "STORAGE_BUCKET": "stock-watchlist-pec.appspot.com",
33 | "MESSAGING_SENDER_ID": "316148951749",
34 | "APP_ID": "1:316148951749:web:3fed8a95e649e78d605eac",
35 | "MEASUREMENT_ID": "G-BQMYPTRNNX",
36 | "ANDROID_CLIENT_ID": "316148951749-eg5o8km0k13u03b8r32phi6v6f8vr3dn.apps.googleusercontent.com",
37 | "IOS_CLIENT_ID": "316148951749-f92vbdc04mughtfsb8feimdr950aedc1.apps.googleusercontent.com",
38 | "ANDROID_STANDALONE_APP_CLIENT_ID": "316148951749-lj3gsji24t5tb07eqjen9ov3jrpvgcjp.apps.googleusercontent.com",
39 | "IOS_STANDALONE_APP_CLIENT_ID": "316148951749-8u2uof18venstiufjg0q4uv0hnp1i5lh.apps.googleusercontent.com",
40 | "EXPO_CLIENT_ID": "316148951749-qhh8q0ebn8dd5b0hfmlsmokom2bqrlpb.apps.googleusercontent.com",
41 | "X_MESSARI_API_KEY": "9f3cc221-44ec-460a-bf7a-8576d8e6dcf9",
42 | "PROXY": "false"
43 | },
44 | "android": {
45 | "buildType": "apk"
46 | },
47 | "ios": {
48 | "simulator": true
49 | }
50 | },
51 | "production": {}
52 | },
53 | "submit": {
54 | "production": {}
55 | }
56 | }
--------------------------------------------------------------------------------
/firebase.js:
--------------------------------------------------------------------------------
1 | import { initializeApp } from 'firebase/app';
2 | // import { getAnalytics } from "firebase/analytics";
3 | import { getAuth } from 'firebase/auth';
4 | import { getFirestore } from 'firebase/firestore';
5 | import {
6 | API_KEY,
7 | APP_ID,
8 | AUTH_DOMAIN,
9 | MEASUREMENT_ID,
10 | MESSAGING_SENDER_ID,
11 | PROJECT_ID,
12 | STORAGE_BUCKET,
13 | } from '@env';
14 |
15 | const firebaseConfig = {
16 | apiKey: API_KEY,
17 | authDomain: AUTH_DOMAIN,
18 | projectId: PROJECT_ID,
19 | storageBucket: STORAGE_BUCKET,
20 | messagingSenderId: MESSAGING_SENDER_ID,
21 | appId: APP_ID,
22 | measurementId: MEASUREMENT_ID,
23 | };
24 |
25 | const app = initializeApp(firebaseConfig);
26 | // const analytics = getAnalytics(app);
27 | const auth = getAuth();
28 | const db = getFirestore();
29 |
30 | export { auth, db };
31 |
--------------------------------------------------------------------------------
/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "316148951749",
4 | "project_id": "stock-watchlist-pec",
5 | "storage_bucket": "stock-watchlist-pec.appspot.com"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:316148951749:android:4b32f9f6d8137bda605eac",
11 | "android_client_info": {
12 | "package_name": "com.stockwatchlist"
13 | }
14 | },
15 | "oauth_client": [
16 | {
17 | "client_id": "316148951749-qhh8q0ebn8dd5b0hfmlsmokom2bqrlpb.apps.googleusercontent.com",
18 | "client_type": 3
19 | }
20 | ],
21 | "api_key": [
22 | {
23 | "current_key": "AIzaSyBlaYemjd3RU6WzFNFKKga1hMymcDRCyB4"
24 | },
25 | {
26 | "current_key": "AIzaSyDMLiuMt15blyfg4Mwx3HOmLmfiNF2Ip5I"
27 | }
28 | ],
29 | "services": {
30 | "appinvite_service": {
31 | "other_platform_oauth_client": [
32 | {
33 | "client_id": "316148951749-qhh8q0ebn8dd5b0hfmlsmokom2bqrlpb.apps.googleusercontent.com",
34 | "client_type": 3
35 | },
36 | {
37 | "client_id": "316148951749-8u2uof18venstiufjg0q4uv0hnp1i5lh.apps.googleusercontent.com",
38 | "client_type": 2,
39 | "ios_info": {
40 | "bundle_id": "com.stockwatchlist"
41 | }
42 | }
43 | ]
44 | }
45 | }
46 | },
47 | {
48 | "client_info": {
49 | "mobilesdk_app_id": "1:316148951749:android:2f00fc308fd3834c605eac",
50 | "android_client_info": {
51 | "package_name": "host.exp.exponent"
52 | }
53 | },
54 | "oauth_client": [
55 | {
56 | "client_id": "316148951749-eg5o8km0k13u03b8r32phi6v6f8vr3dn.apps.googleusercontent.com",
57 | "client_type": 1,
58 | "android_info": {
59 | "package_name": "host.exp.exponent",
60 | "certificate_hash": "53c960c9bad9a5c8fe338eed1bd26f80099f55c1"
61 | }
62 | },
63 | {
64 | "client_id": "316148951749-qhh8q0ebn8dd5b0hfmlsmokom2bqrlpb.apps.googleusercontent.com",
65 | "client_type": 3
66 | }
67 | ],
68 | "api_key": [
69 | {
70 | "current_key": "AIzaSyBlaYemjd3RU6WzFNFKKga1hMymcDRCyB4"
71 | },
72 | {
73 | "current_key": "AIzaSyDMLiuMt15blyfg4Mwx3HOmLmfiNF2Ip5I"
74 | }
75 | ],
76 | "services": {
77 | "appinvite_service": {
78 | "other_platform_oauth_client": [
79 | {
80 | "client_id": "316148951749-qhh8q0ebn8dd5b0hfmlsmokom2bqrlpb.apps.googleusercontent.com",
81 | "client_type": 3
82 | },
83 | {
84 | "client_id": "316148951749-8u2uof18venstiufjg0q4uv0hnp1i5lh.apps.googleusercontent.com",
85 | "client_type": 2,
86 | "ios_info": {
87 | "bundle_id": "com.stockwatchlist"
88 | }
89 | }
90 | ]
91 | }
92 | }
93 | }
94 | ],
95 | "configuration_version": "1"
96 | }
--------------------------------------------------------------------------------
/hooks/useAuth.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | createContext,
3 | useContext,
4 | useEffect,
5 | useMemo,
6 | useState,
7 | } from 'react';
8 | import * as Google from 'expo-auth-session/providers/google';
9 | import * as WebBrowser from 'expo-web-browser';
10 | import {
11 | GoogleAuthProvider,
12 | onAuthStateChanged,
13 | signInWithCredential,
14 | signOut,
15 | } from 'firebase/auth';
16 | import { auth } from '../firebase';
17 | import {
18 | ANDROID_STANDALONE_APP_CLIENT_ID,
19 | IOS_STANDALONE_APP_CLIENT_ID,
20 | EXPO_CLIENT_ID,
21 | } from '@env';
22 |
23 | WebBrowser.maybeCompleteAuthSession();
24 |
25 | const AuthContext = createContext({});
26 |
27 | // const config = {
28 | // androidClientId: ANDROID_CLIENT_ID,
29 | // iosClientId: IOS_CLIENT_ID,
30 | // // androidStandaloneAppClientId: ANDROID_STANDALONE_APP_CLIENT_ID,
31 | // androidStandaloneAppClientId:
32 | // '316148951749-lj3gsji24t5tb07eqjen9ov3jrpvgcjp.apps.googleusercontent.com',
33 | // iosStandaloneAppClientId: IOS_STANDALONE_APP_CLIENT_ID,
34 | // // iosStandaloneAppClientId: '316148951749-f92vbdc04mughtfsb8feimdr950aedc1.apps.googleusercontent.com',
35 | // scopes: ['profile', 'email'],
36 | // permissions: ['public_profile', 'email'],
37 | // };
38 |
39 | export const AuthProvider = ({ children }) => {
40 | const [error, setError] = useState(null);
41 | const [user, setUser] = useState(null);
42 | const [loadingInitial, setLoadingInitial] = useState(true);
43 | const [loading, setLoading] = useState(false);
44 |
45 | const [request, response, promptAsync] = Google.useAuthRequest({
46 | androidClientId: ANDROID_STANDALONE_APP_CLIENT_ID,
47 | iosClientId: IOS_STANDALONE_APP_CLIENT_ID,
48 | expoClientId: EXPO_CLIENT_ID,
49 | });
50 |
51 | useEffect(
52 | () =>
53 | onAuthStateChanged(auth, (user) => {
54 | if (user) {
55 | setUser(user);
56 | } else {
57 | setUser(null);
58 | }
59 | setLoadingInitial(false);
60 | if (loading) setLoading(false);
61 | }),
62 | []
63 | );
64 |
65 | const logout = () => {
66 | setLoading(true);
67 |
68 | signOut(auth)
69 | .catch((error) => setError(error))
70 | .finally(() => setLoading(false));
71 | };
72 |
73 | // const signInWithGoogle = async () => {
74 | // setLoading(true);
75 | // console.log('About to call logInAsync');
76 | // try {
77 | // await Google.logInAsync(config)
78 | // .then(async (logInResult) => {
79 | // console.log(`Got logInResult: ${logInResult.type}`);
80 | // if (logInResult.type === 'success') {
81 | // // login
82 | // const { idToken, accessToken } = logInResult;
83 | // const credential = GoogleAuthProvider.credential(
84 | // idToken,
85 | // accessToken
86 | // );
87 | // await signInWithCredential(auth, credential);
88 | // }
89 | // return Promise.reject();
90 | // })
91 | // .catch((error) => setError(error))
92 | // .finally(() => setLoading(false));
93 | // } catch (error) {
94 | // console.log(error);
95 | // }
96 | // };
97 |
98 | const getUserData = async (idToken, accessToken) => {
99 | const credential = GoogleAuthProvider.credential(idToken, accessToken);
100 | await signInWithCredential(auth, credential);
101 | };
102 |
103 | useEffect(() => {
104 | console.log('response');
105 | if (response?.type === 'success') {
106 | setLoading(true);
107 | console.log(response);
108 | const { idToken, accessToken } = response.authentication;
109 | getUserData(idToken, accessToken);
110 | }
111 | }, [response]);
112 |
113 | const memoedValue = useMemo(
114 | () => ({
115 | user,
116 | loading,
117 | error,
118 | logout,
119 | // signInWithGoogle,
120 | request,
121 | promptAsync,
122 | }),
123 | [user, loading, error, request]
124 | );
125 |
126 | return (
127 |
128 | {!loadingInitial && children}
129 |
130 | );
131 | };
132 |
133 | export default function useAuth() {
134 | return useContext(AuthContext);
135 | }
136 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import { registerRootComponent } from 'expo';
2 |
3 | import App from './App';
4 |
5 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
6 | // It also ensures that whether you load the app in Expo Go or in a native build,
7 | // the environment is set up appropriately
8 | registerRootComponent(App);
9 |
--------------------------------------------------------------------------------
/metro.config.js:
--------------------------------------------------------------------------------
1 | // Learn more https://docs.expo.io/guides/customizing-metro
2 | const { getDefaultConfig } = require('expo/metro-config');
3 |
4 | module.exports = getDefaultConfig(__dirname);
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stock-watchlist",
3 | "version": "1.0.0",
4 | "scripts": {
5 | "start": "expo start",
6 | "android": "expo run:android",
7 | "ios": "expo run:ios",
8 | "web": "expo start --web",
9 | "eject": "expo eject"
10 | },
11 | "dependencies": {
12 | "@expo-google-fonts/montserrat-alternates": "^0.2.2",
13 | "@expo-google-fonts/overpass": "^0.2.2",
14 | "@expo/webpack-config": "^18.0.1",
15 | "@react-navigation/bottom-tabs": "^6.5.2",
16 | "@react-navigation/material-bottom-tabs": "^6.2.10",
17 | "@react-navigation/native": "^6.1.1",
18 | "@react-navigation/native-stack": "^6.9.7",
19 | "deprecated-react-native-prop-types": "^4.0.0",
20 | "expo": "^48.0.0",
21 | "expo-app-loading": "~2.1.1",
22 | "expo-application": "~5.1.1",
23 | "expo-auth-session": "~4.0.3",
24 | "expo-dev-client": "~2.1.6",
25 | "expo-random": "~13.1.1",
26 | "expo-splash-screen": "~0.18.1",
27 | "expo-status-bar": "~1.4.4",
28 | "expo-web-browser": "~12.1.1",
29 | "firebase": "^9.6.2",
30 | "patch-package": "^6.5.0",
31 | "postinstall-postinstall": "^2.1.0",
32 | "react": "18.2.0",
33 | "react-dom": "18.2.0",
34 | "react-native": "0.71.4",
35 | "react-native-app-intro-slider": "^4.0.4",
36 | "react-native-dotenv": "^3.4.6",
37 | "react-native-gesture-handler": "~2.9.0",
38 | "react-native-paper": "^5.1.0",
39 | "react-native-reanimated": "~2.14.4",
40 | "react-native-root-toast": "^3.3.0",
41 | "react-native-safe-area-context": "4.5.0",
42 | "react-native-screens": "~3.20.0",
43 | "react-native-svg": "13.4.0",
44 | "react-native-vector-icons": "^9.0.0",
45 | "react-native-web": "~0.18.7",
46 | "react-navigation": "^4.4.4",
47 | "react-navigation-drawer": "^2.7.1",
48 | "react-navigation-stack": "^2.10.4"
49 | },
50 | "devDependencies": {
51 | "@babel/core": "^7.19.3"
52 | },
53 | "resolutions": {
54 | "@expo/config-plugins": "~6.0.0",
55 | "@expo/prebuild-config": "~6.0.0"
56 | },
57 | "private": true
58 | }
59 |
--------------------------------------------------------------------------------
/patches/react-native+0.70.5.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native/Libraries/Text/Text.js b/node_modules/react-native/Libraries/Text/Text.js
2 | index 57b6a2e..7ba7008 100644
3 | --- a/node_modules/react-native/Libraries/Text/Text.js
4 | +++ b/node_modules/react-native/Libraries/Text/Text.js
5 | @@ -209,6 +209,12 @@ const Text: React.AbstractComponent<
6 |
7 | Text.displayName = 'Text';
8 |
9 | +/**
10 | + * Switch to `deprecated-react-native-prop-types` for compatibility with future
11 | + * releases. This is deprecated and will be removed in the future.
12 | + */
13 | +Text.propTypes = require('deprecated-react-native-prop-types').TextPropTypes;
14 | +
15 | /**
16 | * Returns false until the first time `newValue` is true, after which this will
17 | * always return true. This is necessary to lazily initialize `Pressability` so
18 | diff --git a/node_modules/react-native/index.js b/node_modules/react-native/index.js
19 | index d59ba34..8023167 100644
20 | --- a/node_modules/react-native/index.js
21 | +++ b/node_modules/react-native/index.js
22 | @@ -435,32 +435,16 @@ module.exports = {
23 | },
24 | // Deprecated Prop Types
25 | get ColorPropType(): $FlowFixMe {
26 | - invariant(
27 | - false,
28 | - 'ColorPropType has been removed from React Native. Migrate to ' +
29 | - "ColorPropType exported from 'deprecated-react-native-prop-types'.",
30 | - );
31 | + return require("deprecated-react-native-prop-types").ColorPropType
32 | },
33 | get EdgeInsetsPropType(): $FlowFixMe {
34 | - invariant(
35 | - false,
36 | - 'EdgeInsetsPropType has been removed from React Native. Migrate to ' +
37 | - "EdgeInsetsPropType exported from 'deprecated-react-native-prop-types'.",
38 | - );
39 | + return require("deprecated-react-native-prop-types").EdgeInsetsPropType
40 | },
41 | get PointPropType(): $FlowFixMe {
42 | - invariant(
43 | - false,
44 | - 'PointPropType has been removed from React Native. Migrate to ' +
45 | - "PointPropType exported from 'deprecated-react-native-prop-types'.",
46 | - );
47 | + return require("deprecated-react-native-prop-types").PointPropType
48 | },
49 | get ViewPropTypes(): $FlowFixMe {
50 | - invariant(
51 | - false,
52 | - 'ViewPropTypes has been removed from React Native. Migrate to ' +
53 | - "ViewPropTypes exported from 'deprecated-react-native-prop-types'.",
54 | - );
55 | + return require("deprecated-react-native-prop-types").ViewPropTypes
56 | },
57 | };
58 |
59 |
--------------------------------------------------------------------------------
/routes/StackNavigator.js:
--------------------------------------------------------------------------------
1 | import { createNativeStackNavigator } from '@react-navigation/native-stack';
2 | import React from 'react';
3 | import useAuth from '../hooks/useAuth';
4 | import LoginScreen from '../screens/LoginScreen';
5 | import TabNavigator from './TabNavigator';
6 | import IntroScreen from '../screens/Intro';
7 |
8 | const Stack = createNativeStackNavigator();
9 |
10 | const StackNavigator = () => {
11 | const { user } = useAuth();
12 |
13 | return (
14 |
19 | {/* */}
20 | {user ? (
21 |
22 | ) : (
23 | //
25 | )}
26 |
27 | );
28 | };
29 |
30 | export default StackNavigator;
31 |
--------------------------------------------------------------------------------
/routes/TabNavigator.js:
--------------------------------------------------------------------------------
1 | import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
2 | import { FontAwesome, Ionicons } from '@expo/vector-icons';
3 | import React from 'react';
4 | import SearchScreen from '../screens/SearchScreen';
5 | import StockScreen from '../screens/StockScreen';
6 | import ProfileScreen from '../screens/ProfileScreen';
7 | import AboutScreen from '../screens/AboutScreen';
8 | import WatchListScreen from '../screens/WatchListScreen';
9 |
10 | const Tab = createMaterialBottomTabNavigator();
11 |
12 | const TabNavigator = () => {
13 | return (
14 |
23 | (
29 |
30 | ),
31 | }}
32 | />
33 | (
39 |
40 | ),
41 | }}
42 | />
43 | (
50 |
51 | ),
52 | }}
53 | />
54 | (
60 |
61 | ),
62 | }}
63 | />
64 | (
70 |
71 | ),
72 | }}
73 | />
74 |
75 | );
76 | };
77 |
78 | export default TabNavigator;
79 |
--------------------------------------------------------------------------------
/screens/AboutScreen.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | View,
4 | Text,
5 | SafeAreaView,
6 | StyleSheet,
7 | TouchableOpacity,
8 | ScrollView,
9 | Linking,
10 | } from 'react-native';
11 | import { StatusBar } from 'expo-status-bar';
12 | import Constants from 'expo-constants';
13 | import { useFonts } from 'expo-font';
14 | import AppLoading from 'expo-app-loading';
15 | import Header from '../components/header/headerLoginPage';
16 | import { AntDesign } from '@expo/vector-icons';
17 |
18 | export default function AboutScreen() {
19 | let [fontsLoaded, error] = useFonts({
20 | Ubuntu: require('../assets/fonts/Ubuntu-Medium.ttf'),
21 | });
22 |
23 | if (!fontsLoaded) {
24 | return ;
25 | }
26 |
27 | return (
28 |
29 |
30 |
31 |
32 |
33 | Punjab Engineering College's
34 |
35 | ACM - CSS
36 |
37 | "We are of ACM-CSS PEC, the Computer Science Society of
38 | PEC . Here we do everthing related to the world of
39 | coding ranging from Web Development to Open Source
40 | Contribution"
41 |
42 |
43 |
44 | STOCK WATCHLIST
45 |
46 | What is Stock Watchlist about ? {'\n'} An open source
47 | project developed by ACM-CSS, where you can keep an eye
48 | on how the market changes day-to-day.
49 |
50 |
51 |
52 | CONTACT US
53 |
54 |
55 |
56 |
61 | Linking.openURL(
62 | 'https://www.linkedin.com/company/pec-acm-student-chapter'
63 | )
64 | }
65 | />
66 |
67 | LinkedIn Page of ACM-CSS
68 |
69 |
70 |
71 |
76 | Linking.openURL(
77 | 'https://mobile.twitter.com/pec_acm'
78 | )
79 | }
80 | />
81 |
82 | Twitter Page of ACM-CSS
83 |
84 |
85 |
86 |
91 | Linking.openURL(
92 | 'https://github.com/PEC-CSS'
93 | )
94 | }
95 | />
96 |
97 | Github Page of ACM-CSS
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | Github repository of our open source project
106 |
107 |
112 | Linking.openURL(
113 | 'https://github.com/PEC-CSS/Stock-Watchlist'
114 | )
115 | }
116 | />
117 |
118 |
119 |
120 |
121 | );
122 | }
123 |
124 | const styles = StyleSheet.create({
125 | screen: {
126 | flex: 1,
127 | paddingTop: Constants.statusBarHeight,
128 | backgroundColor: '#f0f8ff',
129 | },
130 | header: {
131 | marginTop: 50,
132 | marginLeft: 5,
133 | },
134 | headerTitle: {
135 | fontFamily: 'Ubuntu',
136 | fontSize: 54,
137 | color: '#161853',
138 | textAlign: 'left',
139 | marginBottom: 20,
140 | paddingTop: 4,
141 | },
142 | headerText: {
143 | padding: 15,
144 | fontSize: 16,
145 | textAlign: 'right',
146 | lineHeight: 26,
147 | },
148 | body: {
149 | backgroundColor: '#b7ddff',
150 | marginTop: 40,
151 | paddingBottom: 30,
152 | paddingRight: 10,
153 | },
154 | bodyTitle: {
155 | fontFamily: 'Ubuntu',
156 | fontSize: 54,
157 | color: '#161853',
158 | textAlign: 'right',
159 | marginBottom: 20,
160 | marginTop: 50,
161 | paddingTop: 4,
162 | },
163 | bodyText: {
164 | padding: 20,
165 | fontSize: 16,
166 | textAlign: 'left',
167 | lineHeight: 26,
168 | color: 'black',
169 | },
170 | contactUs: {
171 | marginBottom: 50,
172 | },
173 | contactTitle: {
174 | fontFamily: 'Ubuntu',
175 | fontSize: 54,
176 | color: '#161853',
177 | marginBottom: 50,
178 | marginTop: 50,
179 | paddingTop: 4,
180 | },
181 | iconContainer: {
182 | flex: 1,
183 | alignItems: 'center',
184 | justifyContent: 'center',
185 | },
186 | icons: {
187 | flexDirection: 'row',
188 | alignItems: 'center',
189 | justifyContent: 'space-between',
190 | marginBottom: 5,
191 | },
192 | iconText: {
193 | fontSize: 18,
194 | marginLeft: 10,
195 | },
196 | footer: {
197 | backgroundColor: '#b7ddff',
198 | height: 200,
199 | marginTop: 30,
200 | flex: 1,
201 | justifyContent: 'center',
202 | alignItems: 'center',
203 | padding: 20,
204 | },
205 | footerText: {
206 | fontSize: 22,
207 | marginBottom: 20,
208 | },
209 | });
210 |
--------------------------------------------------------------------------------
/screens/Intro.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Button, StyleSheet, View, Text, Image, Alert } from 'react-native';
3 | import { StatusBar } from 'expo-status-bar';
4 | import Constants from 'expo-constants';
5 | import { PROXY } from '@env';
6 | import FlatButton from '../shared/button';
7 | import LoginScreen from './LoginScreen';
8 | import useAuth from '../hooks/useAuth';
9 | import AppIntroSlider from 'react-native-app-intro-slider';
10 |
11 | const IntroScreen = () => {
12 | const [showRealApp, setshowRealApp] = useState(false);
13 | // const { signInWithGoogle, loading, error } = useAuth();
14 | const { request, promptAsync, loading, error } = useAuth();
15 |
16 | const createAlert = () => {
17 | Alert.alert('Error', `${error}`, [
18 | {
19 | text: 'Cancel',
20 | style: 'cancel',
21 | },
22 | { text: 'OK' },
23 | ]);
24 | };
25 |
26 | const RenderItem = ({ item }) => {
27 | return (
28 |
38 | {item.title}
39 |
40 | {item.text}
41 | {item.key == 5 && (
42 |
43 |
44 | {loading ? 'Loading . . . ' : 'Login to the app'}
45 |
46 | {
50 | promptAsync({
51 | useProxy: PROXY === 'true' ? true : false,
52 | showInRecents: true,
53 | });
54 | }}
55 | />
56 | {/* {
60 | promptAsync({
61 | useProxy: false,
62 | showInRecents: true,
63 | });
64 | }}
65 | /> */}
66 |
67 | )}
68 |
69 | );
70 | };
71 | return (
72 | <>
73 | {showRealApp ? (
74 |
75 | ) : (
76 |
88 | )}
89 |
90 | {error ? createAlert() : null}
91 | >
92 | );
93 | };
94 |
95 | const styles = StyleSheet.create({
96 | title: {
97 | fontSize: 48,
98 | color: '#151965',
99 | textAlign: 'center',
100 | fontWeight: 'bold',
101 | paddingTop: 100,
102 | marginBottom: 10,
103 | },
104 | text: {
105 | fontSize: 18,
106 | color: '#32407b',
107 | textAlign: 'center',
108 | padding: 30,
109 | lineHeight: 24,
110 | },
111 | image: {
112 | width: 200,
113 | height: 200,
114 | },
115 | logButton: {
116 | position: 'relative',
117 | bottom: 80,
118 | alignItems: 'center',
119 | },
120 | logButtonText: {
121 | fontSize: 24,
122 | fontWeight: 'bold',
123 | margin: 20,
124 | color: '#32407b',
125 | },
126 | });
127 |
128 | const slides = [
129 | {
130 | key: 1,
131 | title: 'WELCOME !',
132 | text: 'Welcome to the #1 ads-free Stock Watchlist App, an Open Source Project by the students of ACM-CSS PEC',
133 | image: require('../assets/welcome.png'),
134 | backgroundColor: '#8cd0e2',
135 | },
136 | {
137 | key: 2,
138 | title: 'ADS FREE',
139 | text: 'A Stock Watchlist App, where you can keep a check on the change, with out getting interupted by ads',
140 | image: require('../assets/adfree.png'),
141 | backgroundColor: '#8cd0e2',
142 | },
143 | {
144 | key: 3,
145 | title: 'ACCURATE',
146 | text: 'No need to worry about wrong stats, just open the app, check the rate and invest with no fear of inaccuracy in change display.',
147 | image: require('../assets/accurate.png'),
148 | backgroundColor: '#8cd0e2',
149 | },
150 | {
151 | key: 4,
152 | title: 'EASY & USER-FRIENDLY',
153 | text: "With it's simple user interface, and easy to use funtions, it makes Stock research 10x Easier ",
154 | image: require('../assets/easytouse.png'),
155 | backgroundColor: '#8cd0e2',
156 | },
157 | {
158 | key: 5,
159 | title: 'GET STARTED',
160 | text: '',
161 | image: require('../assets/getstarted.png'),
162 | backgroundColor: '#8cd0e2',
163 | },
164 | ];
165 |
166 | export default IntroScreen;
167 |
--------------------------------------------------------------------------------
/screens/LoginScreen.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | Text,
5 | View,
6 | ScrollView,
7 | Linking,
8 | Image,
9 | TouchableOpacity,
10 | } from 'react-native';
11 | import useAuth from '../hooks/useAuth';
12 | import FlatButton from '../shared/button';
13 | import { SafeAreaView } from 'react-native-safe-area-context';
14 | import Header from '../components/header/headerLoginPage';
15 | import { useFonts } from 'expo-font';
16 | import AppLoading from 'expo-app-loading';
17 | import { AntDesign } from '@expo/vector-icons';
18 |
19 | const LoginScreen = () => {
20 | const { signInWithGoogle, loading } = useAuth();
21 |
22 | let [fontsLoaded, error] = useFonts({
23 | Overpass: require('../assets/fonts/Overpass-ExtraBold.ttf'),
24 | 'Overpass-light': require('../assets/fonts/Overpass-Light.ttf'),
25 | });
26 |
27 | if (!fontsLoaded) {
28 | return ;
29 | }
30 |
31 | return (
32 |
33 |
34 |
35 | CHECK BEFORE YOU INVEST
36 |
37 |
41 |
42 |
43 |
44 | {loading ? 'Loading . . . ' : 'Login to the app'}
45 |
46 |
50 |
51 |
52 |
53 | This is an open source project made by student branch of
54 | ACM-CSS of Punjab Engineering College.
55 |
56 |
57 |
58 |
63 | Linking.openURL(
64 | 'https://www.linkedin.com/company/pec-acm-student-chapter'
65 | )
66 | }
67 | />
68 |
73 | Linking.openURL(
74 | 'https://mobile.twitter.com/pec_acm'
75 | )
76 | }
77 | />
78 |
83 | Linking.openURL(
84 | 'https://github.com/PEC-CSS'
85 | )
86 | }
87 | />
88 |
89 |
90 |
91 |
92 |
93 | );
94 | };
95 |
96 | const styles = StyleSheet.create({
97 | screen: {
98 | flex: 1,
99 | marginTop: 0,
100 | backgroundColor: '#f0f8ff',
101 | },
102 | imageContainer: {
103 | width: '95%',
104 | height: 400,
105 | alignSelf: 'center',
106 | marginTop: 30,
107 | backgroundColor: 'white',
108 | borderRadius: 30,
109 | },
110 | image: {
111 | width: '90%',
112 | height: '90%',
113 | alignSelf: 'center',
114 | },
115 | slogan: {
116 | textAlign: 'center',
117 | fontFamily: 'Overpass',
118 | fontSize: 48,
119 | marginTop: 25,
120 | lineHeight: 55,
121 | },
122 | logButton: {
123 | alignItems: 'center',
124 | },
125 | logButtonText: {
126 | fontSize: 24,
127 | fontWeight: 'bold',
128 | margin: 20,
129 | },
130 | footer: {
131 | backgroundColor: '#0a2351',
132 | height: 200,
133 | marginTop: 30,
134 | },
135 | footerText: {
136 | color: 'white',
137 | fontFamily: 'Overpass-light',
138 | fontSize: 18,
139 | marginTop: 30,
140 | textAlign: 'center',
141 | },
142 | icons: {
143 | flexDirection: 'row',
144 | justifyContent: 'space-around',
145 | marginTop: 20,
146 | },
147 | });
148 |
149 | export default LoginScreen;
150 |
--------------------------------------------------------------------------------
/screens/ProfileScreen.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | View,
4 | SafeAreaView,
5 | StyleSheet,
6 | TouchableOpacity,
7 | Dimensions,
8 | Text,
9 | ImageBackground,
10 | } from 'react-native';
11 | import { StatusBar } from 'expo-status-bar';
12 | import useAuth, { AuthProvider } from '../hooks/useAuth';
13 | import Constants from 'expo-constants';
14 | // import Logout from '../shared/buttonLogout';
15 | import Header from '../components/header/headerLoginPage';
16 | import { Ionicons } from '@expo/vector-icons';
17 | import { useNavigation } from '@react-navigation/native';
18 | import UserComponent from '../components/profile';
19 |
20 | const window = Dimensions.get('window');
21 |
22 | const Logout = ({ text, onPress }) => {
23 | return (
24 |
25 |
26 | {text}
27 |
28 |
29 | );
30 | };
31 |
32 | export default function ProfileScreen() {
33 | const navigation = useNavigation();
34 | const { user, logout } = useAuth();
35 |
36 | return (
37 |
38 |
39 |
40 |
46 |
47 | {
52 | // console.log(JSON.stringify(user, null, 4));
53 | navigation.navigate('Stocks', {
54 | clicked: true,
55 | });
56 | }}
57 | />
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | );
68 | }
69 |
70 | const styles = StyleSheet.create({
71 | screen: {
72 | flex: 1,
73 | paddingTop: Constants.statusBarHeight,
74 | backgroundColor: '#f0f8ff',
75 | zIndex: 1,
76 | },
77 | container: {
78 | display: 'flex',
79 | flexDirection: 'row',
80 | justifyContent: 'space-between',
81 | alignItems: 'center',
82 | // height: 150,
83 | width: window.width,
84 | zIndex: 2,
85 | },
86 | imageContainer: {
87 | display: 'flex',
88 | flexDirection: 'row',
89 | justifyContent: 'space-between',
90 | alignItems: 'center',
91 | height: 100,
92 | width: window.width,
93 | zIndex: 2,
94 | },
95 | logOut: {
96 | // position: 'relative',
97 | // bottom: 33,
98 | // left: 263,
99 | // width: 350,
100 | },
101 | button: {
102 | backgroundColor: '#0a2351',
103 | borderRadius: 10,
104 | flexDirection: 'row',
105 | alignItems: 'center',
106 | marginRight: 7,
107 | },
108 | buttonText: {
109 | color: 'white',
110 | fontSize: 20,
111 | textAlign: 'center',
112 | fontWeight: 'bold',
113 | margin: 5,
114 | },
115 | });
116 |
--------------------------------------------------------------------------------
/screens/SearchScreen.js:
--------------------------------------------------------------------------------
1 | import { X_MESSARI_API_KEY } from '@env';
2 | import React, { useState, useEffect, useCallback } from 'react';
3 | import {
4 | ActivityIndicator,
5 | SafeAreaView,
6 | StyleSheet,
7 | View,
8 | } from 'react-native';
9 | import { StatusBar } from 'expo-status-bar';
10 | import {
11 | doc,
12 | getDoc,
13 | setDoc,
14 | updateDoc,
15 | arrayUnion,
16 | arrayRemove,
17 | } from 'firebase/firestore';
18 | import Toast from 'react-native-root-toast';
19 | import Constants from 'expo-constants';
20 | import Header from '../components/header/headerLoginPage';
21 | import SearchBar from '../components/search';
22 | import List from '../components/search/suggestion';
23 | import useAuth from '../hooks/useAuth';
24 | import { db } from '../firebase';
25 |
26 | const SearchScreen = (props) => {
27 | const { user } = useAuth();
28 | const docRef = doc(db, 'users', user.uid);
29 | const [refreshing, setRefreshing] = useState(false);
30 | const [searchPhrase, setSearchPhrase] = useState('');
31 | const [clicked, setClicked] = useState(props.route.params.clicked | false);
32 | const [cryptoData, setCrytpoData] = useState({ data: [] });
33 | const [watchlistData, setWatchlistData] = useState([]);
34 | getDoc(docRef).then((docSnap) => {
35 | if (docSnap.exists()) {
36 | console.log('Document data:', docSnap.data());
37 | if (!watchlistData) {
38 | setWatchlistData(docSnap.data().watchlist);
39 | }
40 | } else {
41 | console.log('No such document!');
42 | setDoc(docRef, {
43 | name: user.providerData[0].displayName,
44 | email: user.providerData[0].email,
45 | watchlist: [],
46 | });
47 | }
48 | });
49 | const a = 10;
50 |
51 | const updateWatchlistData = (match, symbol) => {
52 | console.log(match, symbol);
53 | const toastOptions = {};
54 | if (match) {
55 | // symbol present in watchlist. remove it
56 | let toast = Toast.show(
57 | `Removing ${symbol} from watchlist...`,
58 | toastOptions
59 | );
60 | updateDoc(docRef, {
61 | watchlist: arrayRemove(symbol),
62 | });
63 | Toast.hide(toast);
64 | Toast.show(`Removed ${symbol} from watchlist...`, toastOptions);
65 | } else {
66 | // symbol not present in watchlist. add it
67 | let toast = Toast.show(
68 | `Adding ${symbol} to watchlist...`,
69 | toastOptions
70 | );
71 | updateDoc(docRef, {
72 | watchlist: arrayUnion(symbol),
73 | });
74 | Toast.hide(toast);
75 | Toast.show(`Added ${symbol} to watchlist...`, toastOptions);
76 | }
77 | getDoc(docRef).then((docSnap) => {
78 | setWatchlistData(docSnap.data().watchlist);
79 | });
80 | };
81 |
82 | useEffect(() => {
83 | fetch(
84 | 'https://data.messari.io/api/v2/assets?fields=id,symbol,name,metrics/market_data',
85 | {
86 | method: 'GET',
87 | headers: { 'x-messari-api-key': X_MESSARI_API_KEY },
88 | }
89 | )
90 | .then((response) => response.json())
91 | .then((jsonResponse) => setCrytpoData(jsonResponse))
92 | .catch((error) => console.log(error));
93 | // .finally(() => console.log(cryptoData));
94 | getDoc(docRef).then((docSnap) => {
95 | setWatchlistData(docSnap.data().watchlist);
96 | });
97 | }, [a]);
98 |
99 | const onRefresh = useCallback(() => {
100 | setRefreshing(true);
101 | fetch(
102 | 'https://data.messari.io/api/v2/assets?fields=id,symbol,name,metrics/market_data',
103 | {
104 | method: 'GET',
105 | headers: { 'x-messari-api-key': X_MESSARI_API_KEY },
106 | }
107 | )
108 | .then((response) => response.json())
109 | .then((jsonResponse) => setCrytpoData(jsonResponse))
110 | .then(() => setRefreshing(false))
111 | .catch((error) => console.log(error));
112 | // .finally(() => console.log(cryptoData));
113 | getDoc(docRef).then((docSnap) => {
114 | setWatchlistData(docSnap.data().watchlist);
115 | });
116 | }, []);
117 |
118 | return (
119 |
120 |
121 |
122 |
128 | {!cryptoData.data.length ? (
129 |
134 | ) : (
135 |
144 | )}
145 |
146 |
147 |
148 | );
149 | };
150 |
151 | const styles = StyleSheet.create({
152 | root: {
153 | marginTop: Constants.statusBarHeight,
154 | backgroundColor: '#f0f8ff',
155 | },
156 | searchBox: {
157 | justifyContent: 'center',
158 | alignItems: 'center',
159 | },
160 | });
161 |
162 | export default SearchScreen;
163 |
--------------------------------------------------------------------------------
/screens/StockScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useCallback } from 'react';
2 | import {
3 | ActivityIndicator,
4 | FlatList,
5 | SafeAreaView,
6 | StyleSheet,
7 | } from 'react-native';
8 | import { StatusBar } from 'expo-status-bar';
9 | import {
10 | doc,
11 | getDoc,
12 | setDoc,
13 | updateDoc,
14 | arrayUnion,
15 | arrayRemove,
16 | } from 'firebase/firestore';
17 | import Toast from 'react-native-root-toast';
18 | import { X_MESSARI_API_KEY } from '@env';
19 | import Listcard from '../components/Listcard';
20 | import Constants from 'expo-constants';
21 | import Header from '../components/header/headerLoginPage';
22 | import useAuth from '../hooks/useAuth';
23 | import { db } from '../firebase';
24 |
25 | export default function StockScreen() {
26 | const { user } = useAuth();
27 | const docRef = doc(db, 'users', user.uid);
28 | const [refreshing, setRefreshing] = useState(false);
29 | const [cryptoData, setCrytpoData] = useState({ data: [] });
30 | const [watchlistData, setWatchlistData] = useState([]);
31 | getDoc(docRef).then((docSnap) => {
32 | if (docSnap.exists()) {
33 | console.log('Document data:', docSnap.data());
34 | if (!watchlistData) {
35 | setWatchlistData(docSnap.data().watchlist);
36 | }
37 | } else {
38 | console.log('No such document!');
39 | setDoc(docRef, {
40 | name: user.providerData[0].displayName,
41 | email: user.providerData[0].email,
42 | watchlist: [],
43 | });
44 | }
45 | });
46 |
47 | console.log(watchlistData);
48 | const a = 10;
49 |
50 | const updateWatchlistData = (match, symbol) => {
51 | console.log(match, symbol);
52 | const toastOptions = {};
53 | if (match) {
54 | // symbol present in watchlist. remove it
55 | let toast = Toast.show(
56 | `Removing ${symbol} from watchlist...`,
57 | toastOptions
58 | );
59 | updateDoc(docRef, {
60 | watchlist: arrayRemove(symbol),
61 | });
62 | Toast.hide(toast);
63 | Toast.show(`Removed ${symbol} from watchlist...`, toastOptions);
64 | } else {
65 | // symbol not present in watchlist. add it
66 | let toast = Toast.show(
67 | `Adding ${symbol} to watchlist...`,
68 | toastOptions
69 | );
70 | updateDoc(docRef, {
71 | watchlist: arrayUnion(symbol),
72 | });
73 | Toast.hide(toast);
74 | Toast.show(`Added ${symbol} to watchlist...`, toastOptions);
75 | }
76 | getDoc(docRef).then((docSnap) => {
77 | setWatchlistData(docSnap.data().watchlist);
78 | });
79 | };
80 |
81 | useEffect(() => {
82 | fetch(
83 | 'https://data.messari.io/api/v2/assets?fields=id,symbol,name,metrics/market_data',
84 | {
85 | method: 'GET',
86 | headers: { 'x-messari-api-key': X_MESSARI_API_KEY },
87 | }
88 | )
89 | .then((response) => response.json())
90 | .then((jsonResponse) => setCrytpoData(jsonResponse))
91 | .catch((error) => console.log(error));
92 | // .finally(() => console.log(cryptoData));
93 | getDoc(docRef).then((docSnap) => {
94 | setWatchlistData(docSnap.data().watchlist);
95 | });
96 | }, [a]);
97 |
98 | const onRefresh = useCallback(() => {
99 | setRefreshing(true);
100 | fetch(
101 | 'https://data.messari.io/api/v2/assets?fields=id,symbol,name,metrics/market_data',
102 | {
103 | method: 'GET',
104 | headers: { 'x-messari-api-key': X_MESSARI_API_KEY },
105 | }
106 | )
107 | .then((response) => response.json())
108 | .then((jsonResponse) => setCrytpoData(jsonResponse))
109 | .then(() => setRefreshing(false))
110 | .catch((error) => console.log(error));
111 | // .finally(() => console.log(cryptoData));
112 | getDoc(docRef).then((docSnap) => {
113 | setWatchlistData(docSnap.data().watchlist);
114 | });
115 | }, []);
116 |
117 | return (
118 |
119 |
120 | {!cryptoData.data.length && !watchlistData ? (
121 |
126 | ) : (
127 | <>
128 | {/* */}
129 | item.id}
132 | renderItem={({ item }) => (
133 |
138 | console.log(item.symbol, watchlistData)
139 | }
140 | price={
141 | item.metrics.market_data.price_usd < 1.01
142 | ? Math.round(
143 | item.metrics.market_data
144 | .price_usd * 1000000
145 | ) / 1000000
146 | : Math.round(
147 | item.metrics.market_data
148 | .price_usd * 100
149 | ) / 100
150 | }
151 | changeRate={
152 | Math.round(
153 | item.metrics.market_data
154 | .percent_change_usd_last_24_hours *
155 | 100
156 | ) / 100
157 | }
158 | match={watchlistData.includes(item.symbol)}
159 | updateWatchlistData={updateWatchlistData}
160 | />
161 | )}
162 | refreshing={refreshing}
163 | onRefresh={onRefresh}
164 | />
165 | >
166 | )}
167 |
168 |
169 | );
170 | }
171 |
172 | const styles = StyleSheet.create({
173 | screen: {
174 | flex: 1,
175 | paddingTop: Constants.statusBarHeight,
176 | },
177 | });
178 |
--------------------------------------------------------------------------------
/screens/WatchListScreen.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { SafeAreaView, StyleSheet } from 'react-native';
3 | import { StatusBar } from 'expo-status-bar';
4 | import Constants from 'expo-constants';
5 | import Header from '../components/header/headerLoginPage';
6 | import WatchList from '../components/watchlist';
7 |
8 | const WatchListScreen = () => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 | );
16 | };
17 |
18 | const styles = StyleSheet.create({
19 | screen: {
20 | flex: 1,
21 | paddingTop: Constants.statusBarHeight,
22 | backgroundColor: '#f0f8ff',
23 | },
24 | });
25 |
26 | export default WatchListScreen;
27 |
--------------------------------------------------------------------------------
/shared/button.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StyleSheet, TouchableOpacity, View, Text } from 'react-native';
3 | import { AntDesign } from '@expo/vector-icons';
4 |
5 | export default function FlatButton({ text, onPress }) {
6 | return (
7 |
8 |
9 |
15 | {text}
16 |
17 |
18 | );
19 | }
20 |
21 | const styles = StyleSheet.create({
22 | button: {
23 | backgroundColor: '#002D62',
24 | borderRadius: 10,
25 | flexDirection: 'row',
26 | alignItems: 'center',
27 | },
28 | buttonText: {
29 | color: 'white',
30 | fontSize: 20,
31 | textAlign: 'center',
32 | fontWeight: 'bold',
33 | margin: 5,
34 | },
35 | google: {
36 | marginLeft: 10,
37 | },
38 | });
39 |
--------------------------------------------------------------------------------
/shared/buttonLogout.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StyleSheet, TouchableOpacity, View, Text } from 'react-native';
3 |
4 | export default function logoutButton({ text, onPress }) {
5 | return (
6 |
7 |
8 | {text}
9 |
10 |
11 | );
12 | }
13 |
14 | const styles = StyleSheet.create({
15 | button: {
16 | backgroundColor: '#0a2351',
17 | borderRadius: 10,
18 | flexDirection: 'row',
19 | alignItems: 'center',
20 | width: '25%',
21 | },
22 | buttonText: {
23 | color: 'white',
24 | fontSize: 20,
25 | textAlign: 'center',
26 | fontWeight: 'bold',
27 | margin: 5,
28 | },
29 | });
30 |
--------------------------------------------------------------------------------
/static/data/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "currencies": [
3 | {
4 | "id": 0,
5 | "name": "Bitcoin",
6 | "symbol": "BTC",
7 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/1.png",
8 | "price": 41959.66,
9 | "changeRate": 15.31
10 | },
11 | {
12 | "id": 1,
13 | "name": "Ethereum",
14 | "symbol": "ETH",
15 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png",
16 | "price": 3202.39,
17 | "changeRate": -2.10
18 | },
19 | {
20 | "id": 2,
21 | "name": "Tether",
22 | "symbol": "USDT",
23 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png",
24 | "price": 1,
25 | "changeRate": -0.04
26 | },
27 | {
28 | "id": 3,
29 | "name": "Binance Coin",
30 | "symbol": "BNB",
31 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/1839.png",
32 | "price": 454.67,
33 | "changeRate": -12.16
34 | },
35 | {
36 | "id": 4,
37 | "name": "Solana",
38 | "symbol": "SOL",
39 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/5426.png",
40 | "price": 145.50,
41 | "changeRate": 15.31
42 | },
43 | {
44 | "id": 5,
45 | "name": "Cardano",
46 | "symbol": "ADA",
47 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/2010.png",
48 | "price": 1.24,
49 | "changeRate": -7.33
50 | },
51 | {
52 | "id": 6,
53 | "name": "USD Coin",
54 | "symbol": "USDC",
55 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png",
56 | "price": 0.9996,
57 | "changeRate": -0.06
58 | },
59 | {
60 | "id": 7,
61 | "name": "Ripple",
62 | "symbol": "XRP",
63 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/52.png",
64 | "price": 0.7681,
65 | "changeRate": 8.64
66 | },
67 | {
68 | "id": 8,
69 | "name": "Terra",
70 | "symbol": "LUNA",
71 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/4172.png",
72 | "price": 70.16,
73 | "changeRate": -20.26
74 | },
75 | {
76 | "id": 9,
77 | "name": "Polkadot",
78 | "symbol": "DOT",
79 | "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/6636.png",
80 | "price": 25.14,
81 | "changeRate": 3.78
82 | }
83 | ]
84 | }
--------------------------------------------------------------------------------
/utils/documentation/Crypto Data API.md:
--------------------------------------------------------------------------------
1 | - LunarCRUSH provides API endpoints for thousands of crypto assets. This is the same API that drives their web app. Access over 100 million collected social posts, all classified by coin using artificial intelligence and displayed alongside unique insights. The cryptocurrency focused company collects more than 100,000 social posts with 20,000 links per day and they support more than 2000 cryptocurrencies. LunarCRUSH is known as one the most reliable API for community and social insights.
2 |
3 | - LunarCRUSH collects data on influencers, social influencer activity and their engagement, frequency, and impact across over thousands of cryptocurrencies. This allows for some pretty awesome things such as how bullish something is vs. bearish. It also lets you know who is really influential vs. a bot. You can also integrate social metrics for over 2,000 coins into your TradingView charts. LunarCRUSH has real-time cryptocurrency alerts, LunarAlerts, for notifications on Cryptocurrency prices and social metrics which helps for automating trade decisions.
4 |
5 | - Messari provides API endpoints for thousands of crypto assets. These endpoints include trades, market data (VWAP), quantitative metrics, qualitative information. This is the same API that drives their web app. Most of their endpoints are available without an API key, but they limit their rates. The free tier does not include redistribution rights and requires attribution and a link back to their site.
6 |
7 | - Nomics is a cryptocurrency data API focused on Price, crypto market cap, supply, and all-time high data. They offer Candle/OHLC data for currencies & exchanges. Additionally, they supply historical aggregate cryptocurrency market cap since January of 2013.
8 | Nomics API is a resource for all developers. Their prices can seem expensive to the typical developer who is searching for a cheap or free crypto API. Nonetheless, they are a well respected API within the crypto industry.
9 |
10 | I propose creating an aggregated model which gets data from multiple APIs.
11 |
12 |
13 | # Alternative
14 | - API Key: 5AD6VSONRP5W8GV6 : https://www.alphavantage.co/documentation/#digital-currency
15 | - Full Data: https://min-api.cryptocompare.com/documentation?key=Price&cat=multipleSymbolsFullPriceEndpoint
16 | - return live price of different Cryptocurrency
17 | Sockets
18 | - https://docs.coincap.io/#37dcec0b-1f7b-4d98-b152-0217a6798058
19 | - https://docs.ftx.com/#rest-api
20 |
--------------------------------------------------------------------------------
/utils/documentation/Stock news API.md:
--------------------------------------------------------------------------------
1 | # Crypto News API
2 | - API Key: 230f9fa4f228ec167a66a70c152d4bfc0c8b669f - https://cryptopanic.com/developers/api/
3 | - /api/v1/posts/?auth_token=230f9fa4f228ec167a66a70c152d4bfc0c8b669f
4 | - Sample response (results is and array of objects - get title of each):
5 | {
6 | "count":200,
7 | "next":"https:\/\/cryptopanic.com\/api\/v1\/posts\/?auth_token=230f9fa4f228ec167a66a70c152d4bfc0c8b669f¤cies=BTC%2CETH&page=2",
8 | "previous":null,
9 | "results":[
10 | {
11 | "kind":"news",
12 | "domain":"theblockcrypto.com",
13 | "source":{
14 | "title":"The Block",
15 | "region":"en",
16 | "domain":"theblockcrypto.com",
17 | "path":null
18 | },
19 | "title":"Visa and ConsenSys team up on CBDC tech",
20 | "published_at":"2022-01-13T05:01:53Z",
21 | "slug":"Visa-and-ConsenSys-team-up-on-CBDC-tech",
22 | "currencies":[
23 | {
24 | "code":"ETH",
25 | "title":"Ethereum",
26 | "slug":"ethereum",
27 | "url":"https:\/\/cryptopanic.com\/news\/ethereum\/"
28 | }
29 | ],
30 | "id":13948205,
31 | "url":"https:\/\/cryptopanic.com\/news\/13948205\/Visa-and-ConsenSys-team-up-on-CBDC-tech",
32 | "created_at":"2022-01-13T05:01:53Z",
33 | "votes":{
34 | "negative":0,
35 | "positive":0,
36 | "important":0,
37 | "liked":0,
38 | "disliked":0,
39 | "lol":0,
40 | "toxic":0,
41 | "saved":0,
42 | "comments":0
43 | }
44 | },{
45 | "kind":"news",
46 | "domain":"newsbtc.com",
47 | "source":{
48 | "title":"NewsBTC",
49 | "region":"en",
50 | "domain":"newsbtc.com",
51 | "path":null
52 | },
53 | "title":"Bribe Looks to Usher In DAO 2.0 With Voter Extractable Value",
54 | "published_at":"2022-01-13T03:23:14Z",
55 | "slug":"Bribe-Looks-to-Usher-In-DAO-20-With-Voter-Extractable-Value",
56 | "currencies":[
57 | {
58 |
59 |
60 |
--------------------------------------------------------------------------------