├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── android.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── app
├── .gitignore
├── assets
│ └── leetdroid_collage.png
├── build.gradle
├── proguard-rules.pro
├── release
│ ├── app-release.aab
│ ├── app-release.apk
│ └── output-metadata.json
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── cdhiraj40
│ │ └── leetdroid
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── licenses.json
│ ├── java
│ │ └── com
│ │ │ └── cdhiraj40
│ │ │ └── leetdroid
│ │ │ ├── adapter
│ │ │ ├── AllQuestionsAdapter.kt
│ │ │ ├── ContestHistoryAdapter.kt
│ │ │ ├── ContestPagerAdapter.kt
│ │ │ ├── ContributorListAdapter.kt
│ │ │ ├── GeneralDiscussionAdapter.kt
│ │ │ ├── LicenseListAdapter.kt
│ │ │ ├── QuestionDiscussionAdapter.kt
│ │ │ ├── RecentSubmissionsAdapter.kt
│ │ │ └── TrendingDiscussionAdapter.kt
│ │ │ ├── api
│ │ │ ├── ApiResponseListener.kt
│ │ │ ├── ContestApi.kt
│ │ │ ├── GithubApi.kt
│ │ │ ├── LeetCodeRequests.kt
│ │ │ └── URL.kt
│ │ │ ├── data
│ │ │ ├── dao
│ │ │ │ ├── ContestDao.kt
│ │ │ │ ├── DailyQuestionDao.kt
│ │ │ │ ├── FirebaseUserDao.kt
│ │ │ │ ├── QuestionsDao.kt
│ │ │ │ └── UserDao.kt
│ │ │ ├── db
│ │ │ │ ├── ContestsDatabase.kt
│ │ │ │ ├── DailyQuestionDatabase.kt
│ │ │ │ ├── FirebaseUserDatabase.kt
│ │ │ │ ├── QuestionDatabase.kt
│ │ │ │ └── UserDatabase.kt
│ │ │ ├── entitiy
│ │ │ │ ├── AllQuestions.kt
│ │ │ │ ├── Contest.kt
│ │ │ │ ├── DailyQuestion.kt
│ │ │ │ ├── FirebaseUserProfile.kt
│ │ │ │ └── User.kt
│ │ │ ├── repository
│ │ │ │ ├── ContestRepository.kt
│ │ │ │ ├── DailyQuestionRepository.kt
│ │ │ │ ├── FirebaseUserRepository.kt
│ │ │ │ └── UserRepository.kt
│ │ │ └── viewModel
│ │ │ │ ├── ConnectionLiveData.kt
│ │ │ │ ├── ContestViewModel.kt
│ │ │ │ ├── DailyQuestionViewModel.kt
│ │ │ │ ├── FirebaseUserViewModel.kt
│ │ │ │ └── UserViewModel.kt
│ │ │ ├── model
│ │ │ ├── AllQuestionsErrorModel.kt
│ │ │ ├── AllQuestionsModel.kt
│ │ │ ├── ContestRankingModel.kt
│ │ │ ├── ContestsModel.kt
│ │ │ ├── ContributorListModel.kt
│ │ │ ├── DailyQuestionModel.kt
│ │ │ ├── DiscussionItemModel.kt
│ │ │ ├── FirebaseUserModel.kt
│ │ │ ├── GeneralDiscussionItemModel.kt
│ │ │ ├── GeneralDiscussionModel.kt
│ │ │ ├── LicensesModel.kt
│ │ │ ├── QuestionContentModel.kt
│ │ │ ├── QuestionDiscussionsModel.kt
│ │ │ ├── QuestionSolutionModel.kt
│ │ │ ├── RandomQuestionModel.kt
│ │ │ ├── RecentSubmissionsModel.kt
│ │ │ ├── TrendingDiscussionModel.kt
│ │ │ ├── UserProfileErrorModel.kt
│ │ │ └── UserProfileModel.kt
│ │ │ ├── notification
│ │ │ ├── DailyQuestionAlarmReceiver.kt
│ │ │ ├── DayContestAlarmReceiver.kt
│ │ │ ├── MinContestAlarmReceiver.kt
│ │ │ └── Notification.kt
│ │ │ ├── sharedViewModel
│ │ │ ├── QuestionDiscussionSharedViewModel.kt
│ │ │ └── QuestionSharedViewModel.kt
│ │ │ ├── ui
│ │ │ ├── authentication
│ │ │ │ ├── ForgotPasswordActivity.kt
│ │ │ │ ├── LoginActivity.kt
│ │ │ │ └── SignUpActivity.kt
│ │ │ ├── base
│ │ │ │ ├── BaseFragment.kt
│ │ │ │ └── MainActivity.kt
│ │ │ └── fragments
│ │ │ │ ├── AllQuestionsFragment.kt
│ │ │ │ ├── ExploreProblemsFragment.kt
│ │ │ │ ├── HomeFragment.kt
│ │ │ │ ├── discussion
│ │ │ │ ├── GeneralDiscussionFragment.kt
│ │ │ │ ├── GeneralDiscussionItemFragment.kt
│ │ │ │ └── TrendingDiscussionFragment.kt
│ │ │ │ ├── preferences
│ │ │ │ ├── AboutFragment.kt
│ │ │ │ ├── ContributorsFragment.kt
│ │ │ │ └── LicenseFragment.kt
│ │ │ │ ├── question
│ │ │ │ ├── DiscussionItemFragment.kt
│ │ │ │ ├── QuestionDiscussionFragment.kt
│ │ │ │ ├── QuestionFragment.kt
│ │ │ │ └── QuestionSolutionFragment.kt
│ │ │ │ └── user
│ │ │ │ ├── ContestDetailsFragment.kt
│ │ │ │ ├── MyProfileFragment.kt
│ │ │ │ └── RecentSubmissionFragment.kt
│ │ │ └── utils
│ │ │ ├── AlarmUtils.kt
│ │ │ ├── CommonFunctions.kt
│ │ │ ├── CommonUtils.kt
│ │ │ ├── Constant.kt
│ │ │ ├── Converters.kt
│ │ │ ├── DateUtils.kt
│ │ │ ├── JsonUtils.kt
│ │ │ ├── LeetDroidGlideModule.kt
│ │ │ ├── NetworkUtils.kt
│ │ │ ├── SharedPreferences.kt
│ │ │ ├── StringExtensions.kt
│ │ │ ├── closeKeyboard.kt
│ │ │ ├── dialog
│ │ │ ├── AlertDialogShower.kt
│ │ │ ├── AppDialogs.kt
│ │ │ └── DialogShower.kt
│ │ │ └── extensions
│ │ │ ├── ContextExtensions.kt
│ │ │ └── FragmentExtensions.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── app_banner.png
│ │ ├── app_icon.png
│ │ ├── app_logo.png
│ │ ├── btn_blue_normal.xml
│ │ ├── btn_blue_pressed.xml
│ │ ├── btn_blue_selector.xml
│ │ ├── circle.xml
│ │ ├── contest_selected_dot_blue.xml
│ │ ├── contest_selected_dot_orange.xml
│ │ ├── contest_selected_dot_white.xml
│ │ ├── contest_unselected_dot_blue.xml
│ │ ├── contest_unselected_dot_orange.xml
│ │ ├── contest_unselected_dot_white.xml
│ │ ├── contest_viewpager_selector_white.xml
│ │ ├── dark_glass_background.xml
│ │ ├── ic_baseline_all_inbox_24.xml
│ │ ├── ic_baseline_arrow_back_24.xml
│ │ ├── ic_baseline_arrow_drop_down_24.xml
│ │ ├── ic_baseline_beenhere_24.xml
│ │ ├── ic_baseline_bug_report_24.xml
│ │ ├── ic_baseline_code_24.xml
│ │ ├── ic_baseline_computer_24.xml
│ │ ├── ic_baseline_content_copy_24.xml
│ │ ├── ic_baseline_discuss_24.xml
│ │ ├── ic_baseline_earbuds_24.xml
│ │ ├── ic_baseline_edit_calendar_24.xml
│ │ ├── ic_baseline_filter_list_24.xml
│ │ ├── ic_baseline_folder_24.xml
│ │ ├── ic_baseline_gesture_24.xml
│ │ ├── ic_baseline_home_24.xml
│ │ ├── ic_baseline_info_24.xml
│ │ ├── ic_baseline_link_24.xml
│ │ ├── ic_baseline_location_on_24.xml
│ │ ├── ic_baseline_logout_24.xml
│ │ ├── ic_baseline_menu_book_20.xml
│ │ ├── ic_baseline_new_releases_24.xml
│ │ ├── ic_baseline_open_in_new_24.xml
│ │ ├── ic_baseline_search_24.xml
│ │ ├── ic_baseline_share_24.xml
│ │ ├── ic_baseline_shuffle_24.xml
│ │ ├── ic_baseline_star_rate_24.xml
│ │ ├── ic_baseline_sync_24.xml
│ │ ├── ic_baseline_topic_24.xml
│ │ ├── ic_baseline_view_list_24.xml
│ │ ├── ic_baseline_views_24.xml
│ │ ├── ic_baseline_warning_24.xml
│ │ ├── ic_contribute.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_question_solution.xml
│ │ ├── ic_round_person_24.xml
│ │ ├── layout_border.xml
│ │ ├── light_glass_background.xml
│ │ ├── like.png
│ │ ├── login_layout_background.xml
│ │ ├── question_icon.png
│ │ ├── question_solution.png
│ │ └── round_background.xml
│ │ ├── layout
│ │ ├── activity_forgot_password.xml
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ ├── activity_sign_up.xml
│ │ ├── all_questions_item.xml
│ │ ├── content_main.xml
│ │ ├── contest_pager_item.xml
│ │ ├── contest_ranking_history_item.xml
│ │ ├── contibutors_item.xml
│ │ ├── drawer_header.xml
│ │ ├── fragment_about.xml
│ │ ├── fragment_all_questions.xml
│ │ ├── fragment_contest_details.xml
│ │ ├── fragment_contributors.xml
│ │ ├── fragment_discussion_item.xml
│ │ ├── fragment_explore_problems.xml
│ │ ├── fragment_general_discussion.xml
│ │ ├── fragment_general_discussion_item.xml
│ │ ├── fragment_home.xml
│ │ ├── fragment_license.xml
│ │ ├── fragment_my_profile.xml
│ │ ├── fragment_question.xml
│ │ ├── fragment_question_discussion.xml
│ │ ├── fragment_question_solution.xml
│ │ ├── fragment_recent_submission.xml
│ │ ├── fragment_trending_discussion.xml
│ │ ├── general_discussion_item.xml
│ │ ├── general_error_layout.xml
│ │ ├── layout_no_questions_search.xml
│ │ ├── layout_no_solution.xml
│ │ ├── layout_paid_question.xml
│ │ ├── license_item.xml
│ │ ├── loading_screen_layout.xml
│ │ ├── nav_header.xml
│ │ ├── question_discussion_item.xml
│ │ ├── recent_submissions_item.xml
│ │ ├── toolbar.xml
│ │ └── trending_discussion_item.xml
│ │ ├── menu
│ │ ├── all_questions_list_menu.xml
│ │ ├── general_discussion_menu.xml
│ │ ├── main_activity_menu.xml
│ │ ├── my_profile_menu.xml
│ │ ├── navigation_drawer_menu.xml
│ │ ├── navigation_menu.xml
│ │ └── navigation_question.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── navigation
│ │ └── nav_graph.xml
│ │ ├── raw
│ │ ├── horizontal_loading_anim.json
│ │ ├── loading_anim.json
│ │ ├── no_result.json
│ │ ├── paid.json
│ │ └── something_went_wrong.json
│ │ ├── values-night
│ │ ├── strings_others.xml
│ │ └── themes.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── string_all_questions.xml
│ │ ├── string_authentication.xml
│ │ ├── string_dialogs.xml
│ │ ├── string_home.xml
│ │ ├── string_problems.xml
│ │ ├── string_programming_languages.xml
│ │ ├── string_question_solution.xml
│ │ ├── string_recent_submissions.xml
│ │ ├── strings.xml
│ │ ├── strings_general_discussions.xml
│ │ ├── strings_myprofile.xml
│ │ ├── strings_question.xml
│ │ └── themes.xml
│ │ └── xml
│ │ └── preferences_about.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── cdhiraj40
│ ├── ExampleUnitTest.kt
│ ├── TimeZoneUTCRule.kt
│ └── utils
│ └── DateUtilsTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: cdhiraj40
4 | custom: https://buymeacoffee.com/cdhiraj40
5 |
6 |
--------------------------------------------------------------------------------
/.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 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Additional context**
27 | Add any other context about the problem here.
28 |
--------------------------------------------------------------------------------
/.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 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
4 |
5 | Fixes # (issue_number)
6 |
7 | ## Screen recording
8 | Add a screen recording showing the changes, if UI/UX changes are done.
9 |
10 | # Checklist:
11 |
12 | - [ ] My code follows the style guidelines of this project
13 | - [ ] I have performed a self-review of my own code
14 | - [ ] I have commented my code, particularly in hard-to-understand areas
15 | - [ ] My changes generate no new warnings
16 |
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - '**'
7 | pull_request:
8 | branches:
9 | - '**'
10 |
11 | jobs:
12 | build:
13 |
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 | - name: set up JDK 11
19 | uses: actions/setup-java@v2
20 | with:
21 | java-version: '11'
22 | distribution: 'temurin'
23 | cache: gradle
24 |
25 | - name: Grant execute permission for gradlew
26 | run: chmod +x gradlew
27 | - name: Build with Gradle
28 | run: ./gradlew build
29 |
30 | - name: Android Test Report
31 | uses: asadmansr/android-test-report-action@v1.2.0
32 | if: ${{ always() }} # IMPORTANT: run Android Test Report regardless
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /.idea
4 | /local.properties
5 | /.idea/caches
6 | /.idea/libraries
7 | /.idea/modules.xml
8 | /.idea/workspace.xml
9 | /.idea/navEditor.xml
10 | /.idea/assetWizardSettings.xml
11 | .DS_Store
12 | /build
13 | /captures
14 | .externalNativeBuild
15 | .cxx
16 | local.properties
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Dhiraj Chauhan
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 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/assets/leetdroid_collage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/assets/leetdroid_collage.png
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/release/app-release.aab:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/release/app-release.aab
--------------------------------------------------------------------------------
/app/release/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/release/app-release.apk
--------------------------------------------------------------------------------
/app/release/output-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "artifactType": {
4 | "type": "APK",
5 | "kind": "Directory"
6 | },
7 | "applicationId": "com.cdhiraj40.leetdroid",
8 | "variantName": "release",
9 | "elements": [
10 | {
11 | "type": "SINGLE",
12 | "filters": [],
13 | "attributes": [],
14 | "versionCode": 1,
15 | "versionName": "1.0",
16 | "outputFile": "app-release.apk"
17 | }
18 | ],
19 | "elementType": "File"
20 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/cdhiraj40/leetdroid/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.example.leetdroid", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
17 |
22 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
45 |
46 |
49 |
52 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/adapter/ContestHistoryAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.adapter
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.TextView
8 | import androidx.recyclerview.widget.RecyclerView
9 | import com.cdhiraj40.leetdroid.R
10 | import com.cdhiraj40.leetdroid.model.ContestRankingModel
11 | import java.text.ParseException
12 | import java.text.SimpleDateFormat
13 | import java.util.*
14 |
15 | class ContestHistoryAdapter(val context: Context) :
16 | RecyclerView.Adapter() {
17 |
18 | private var contestList = ContestRankingModel()
19 | private lateinit var contests: List
20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
21 |
22 | val view = LayoutInflater.from(parent.context)
23 | .inflate(R.layout.contest_ranking_history_item, parent, false)
24 |
25 | return ViewHolder(view)
26 | }
27 |
28 | fun setData(contestsList: ContestRankingModel) {
29 | contestList = contestsList
30 |
31 | // to get the latest contest
32 | contests =
33 | contestsList.data?.userContestRankingHistory!!.sortedByDescending { it.contest?.startTime }
34 | }
35 |
36 | private var onClick: OnItemClicked? = null
37 |
38 | interface OnItemClicked {
39 | fun onItemClick(
40 | position: Int
41 | )
42 | }
43 |
44 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
45 |
46 | val contestItem = contests[position]
47 |
48 | // sets the title of a contest to the textView from our itemHolder class
49 | holder.contestTitle.text =
50 | contestItem.contest?.title
51 |
52 | if (contestItem.ranking!! <= 0L) {
53 | holder.contestRanking.text = context.getString(R.string.user_absent_contest)
54 | } else {
55 | holder.contestRanking.text = contestItem.ranking.toString()
56 | }
57 |
58 |
59 | holder.afterContestRating.text =
60 | contestItem.rating.toString()
61 |
62 |
63 | // setting thw date of contest
64 | val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
65 | val time = format.format(contestItem.contest?.startTime!!.toLong().times(1000L))
66 | var date: Date? = null
67 | try {
68 | date = format.parse(time)
69 | holder.contestDate.text =
70 | SimpleDateFormat("MMM dd, yyyy", Locale.getDefault()).format(date!!)
71 | } catch (e: ParseException) {
72 | e.printStackTrace()
73 | }
74 |
75 | holder.itemView.setOnClickListener {
76 | onClick!!.onItemClick(
77 | position
78 | )
79 | }
80 | }
81 |
82 |
83 | // return the number of the items in the list
84 | override fun getItemCount(): Int {
85 | return contests.size
86 | }
87 |
88 | class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
89 | val contestTitle: TextView = itemView.findViewById(R.id.item_title)
90 | val contestRanking: TextView = itemView.findViewById(R.id.item_contest_ranking)
91 | val contestDate: TextView = itemView.findViewById(R.id.item_date)
92 | val afterContestRating: TextView = itemView.findViewById(R.id.item_after_rating)
93 | }
94 |
95 | fun setOnClick(onClick: OnItemClicked?) {
96 | this.onClick = onClick
97 | }
98 | }
99 |
100 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/adapter/ContributorListAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.adapter
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.ImageView
8 | import android.widget.TextView
9 | import androidx.recyclerview.widget.RecyclerView
10 | import com.bumptech.glide.Glide
11 | import com.cdhiraj40.leetdroid.R
12 | import com.cdhiraj40.leetdroid.model.ContributorListModel
13 | import java.util.*
14 |
15 | class ContributorListAdapter(
16 | val context: Context,
17 | private val contributorClickInterface: ContributorClickInterface,
18 | private val allContributors: ArrayList
19 | ) :
20 | RecyclerView.Adapter() {
21 |
22 | interface ContributorClickInterface {
23 | fun onContributorClick(contributor: ContributorListModel.ContributorListModelItem)
24 | }
25 |
26 |
27 | inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
28 | val contributorAuthor: TextView = itemView.findViewById(R.id.contributor_username)
29 | val contributorAuthorAvatar: ImageView =
30 | itemView.findViewById(R.id.contributor_username_avatar)
31 | }
32 |
33 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
34 | val itemView = LayoutInflater.from(parent.context).inflate(
35 | R.layout.contibutors_item,
36 | parent, false
37 | )
38 |
39 | return ViewHolder(itemView)
40 | }
41 |
42 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
43 |
44 | val contributor = allContributors[position]
45 | holder.contributorAuthor.text = contributor.author?.login
46 |
47 | Glide.with(context)
48 | .load(contributor.author?.avatar_url)
49 | .circleCrop()
50 | .placeholder(android.R.drawable.progress_indeterminate_horizontal)
51 | .into(holder.contributorAuthorAvatar)
52 |
53 | holder.itemView.setOnClickListener {
54 | contributorClickInterface.onContributorClick(contributor)
55 | }
56 | }
57 |
58 | override fun getItemCount(): Int {
59 | return allContributors.size
60 | }
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/adapter/LicenseListAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.adapter
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.TextView
8 | import androidx.recyclerview.widget.RecyclerView
9 | import com.cdhiraj40.leetdroid.R
10 | import com.cdhiraj40.leetdroid.model.LicensesModel
11 |
12 | class LicenseListAdapter(val context: Context) :
13 | RecyclerView.Adapter() {
14 |
15 | private var licenseList = LicensesModel()
16 | private lateinit var licenses: List
17 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
18 |
19 | val view = LayoutInflater.from(parent.context)
20 | .inflate(R.layout.license_item, parent, false)
21 |
22 | return ViewHolder(view)
23 | }
24 |
25 | fun setData(licensesModel: LicensesModel) {
26 | licenseList = licensesModel
27 | licenses = licensesModel.libraries?.library!!
28 | }
29 |
30 | private var onClick: OnItemClicked? = null
31 |
32 | interface OnItemClicked {
33 | fun onItemClick(
34 | position: Int,
35 | website: String?
36 | )
37 | }
38 |
39 | // binds the list items to a view
40 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
41 |
42 | val licenseItem = licenses[position]
43 |
44 | // sets the title of a question to the textView from our itemHolder class
45 | holder.licenseTitle.text =
46 | licenseItem.name
47 |
48 | holder.licenseSubTitle.text =
49 | "By ${licenseItem.author}, ${licenseItem.license}"
50 |
51 | holder.itemView.setOnClickListener {
52 | onClick!!.onItemClick(
53 | position,
54 | licenseItem.website
55 | )
56 | }
57 |
58 | }
59 |
60 |
61 | // return the number of the items in the list
62 | override fun getItemCount(): Int {
63 | return licenses.size
64 | }
65 |
66 | fun getDataItemCount(): Int {
67 | return licenses.size
68 | }
69 |
70 | class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
71 | val licenseTitle: TextView = itemView.findViewById(R.id.license_title)
72 | val licenseSubTitle: TextView = itemView.findViewById(R.id.license_sub_title)
73 | }
74 |
75 | fun setOnClick(onClick: OnItemClicked?) {
76 | this.onClick = onClick
77 | }
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/api/ApiResponseListener.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.api
2 |
3 | interface ApiResponseListener {
4 | fun onSuccess(success: Boolean)
5 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/api/ContestApi.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.api
2 |
3 | import com.google.gson.JsonArray
4 | import retrofit2.Call
5 | import retrofit2.Retrofit
6 | import retrofit2.converter.gson.GsonConverterFactory
7 | import retrofit2.http.GET
8 |
9 | /**
10 | * Retrofit Api call to get upcoming contests
11 | */
12 | interface ContestApi {
13 | @GET("leet_code")
14 | fun getContent(): Call
15 |
16 | companion object {
17 | fun create(): ContestApi {
18 | val retrofit = Retrofit.Builder()
19 | .addConverterFactory(GsonConverterFactory.create())
20 | .baseUrl(URL.leetcodeUpcomingContest)
21 | .build()
22 | return retrofit.create(ContestApi::class.java)
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/api/GithubApi.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.api
2 |
3 | import com.cdhiraj40.leetdroid.model.ContributorListModel
4 | import retrofit2.Call
5 | import retrofit2.Retrofit
6 | import retrofit2.converter.gson.GsonConverterFactory
7 | import retrofit2.http.GET
8 | import retrofit2.http.Path
9 |
10 | interface GithubApi {
11 | @GET("repos/{owner}/{repo}/stats/contributors")
12 | fun getContributors(
13 | @Path("owner") owner: String?,
14 | @Path("repo") repositoryName: String
15 | ): Call
16 |
17 | companion object {
18 | fun create(): GithubApi {
19 | val retrofit = Retrofit.Builder()
20 | .addConverterFactory(GsonConverterFactory.create())
21 | .baseUrl(URL.githubApi)
22 | .build()
23 | return retrofit.create(GithubApi::class.java)
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/api/URL.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.api
2 |
3 | /**
4 | * Has all the URLs used for APIs in the app.
5 | */
6 | object URL {
7 | // LeetCode's main URL
8 | const val leetcode = "https://leetcode.com"
9 |
10 | // URL for LeetCode's GraphQL API
11 | const val graphql = "https://leetcode.com/graphql"
12 |
13 | // URL for Leetcode's Upcoming Contest API
14 | const val leetcodeUpcomingContest = "https://kontests.net/api/v1/"
15 |
16 | const val githubApi = "https://api.github.com/"
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/dao/ContestDao.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.dao
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import com.cdhiraj40.leetdroid.data.entitiy.Contest
6 |
7 | @Dao
8 | interface ContestDao {
9 |
10 | @Insert(onConflict = OnConflictStrategy.REPLACE)
11 | suspend fun insertContest(model: Contest?): Long
12 |
13 | @Update(onConflict = OnConflictStrategy.REPLACE)
14 | suspend fun updateContest(model: Contest?)
15 |
16 | @Query("DELETE FROM contests WHERE id=:id")
17 | suspend fun deleteContest(id: Int)
18 |
19 | @Query("SELECT * FROM contests")
20 | fun getAllContest(): LiveData>
21 |
22 | @Query("SELECT * FROM contests WHERE id=:id ")
23 | suspend fun getContest(id: Int): Contest
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/dao/DailyQuestionDao.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.dao
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import androidx.room.Dao
6 | import com.cdhiraj40.leetdroid.data.entitiy.DailyQuestion
7 |
8 | @Dao
9 | interface DailyQuestionDao {
10 |
11 | @Insert(onConflict = OnConflictStrategy.REPLACE)
12 | suspend fun insertQuestion(user: DailyQuestion?)
13 |
14 | @Update(onConflict = OnConflictStrategy.REPLACE)
15 | suspend fun updateQuestion(user: DailyQuestion?)
16 |
17 | @Query("DELETE FROM daily_question WHERE id=:id")
18 | suspend fun deleteQuestion(id: Int)
19 |
20 | @Query("SELECT * FROM daily_question WHERE id=:id ")
21 | fun getQuestion(id:Int): LiveData
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/dao/FirebaseUserDao.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.dao
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import androidx.room.Dao
6 | import com.cdhiraj40.leetdroid.data.entitiy.FirebaseUserProfile
7 |
8 | @Dao
9 | interface FirebaseUserDao {
10 |
11 | @Insert(onConflict = OnConflictStrategy.REPLACE)
12 | suspend fun insertUser(userProfile: FirebaseUserProfile?)
13 |
14 | @Update(onConflict = OnConflictStrategy.REPLACE)
15 | suspend fun updateUser(userProfile: FirebaseUserProfile?)
16 |
17 | @Query("DELETE FROM firebase_user WHERE id=:id")
18 | suspend fun deleteUser(id: Int)
19 |
20 | @Query("SELECT * FROM firebase_user WHERE id=:id ")
21 | fun getUser(id:Int): LiveData
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/dao/QuestionsDao.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.dao
2 |
3 | import androidx.room.*
4 | import androidx.room.Dao
5 | import com.cdhiraj40.leetdroid.data.entitiy.AllQuestions
6 |
7 | @Dao
8 | interface QuestionsDao {
9 |
10 | @Insert
11 | fun insert(model: AllQuestions?)
12 |
13 | @Update
14 | fun update(model: AllQuestions?)
15 |
16 |
17 | @Query("SELECT * FROM all_questions")
18 | suspend fun getAllQuestions():List
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/dao/UserDao.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.dao
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.room.*
5 | import com.cdhiraj40.leetdroid.data.entitiy.User
6 |
7 | @Dao
8 | interface UserDao {
9 |
10 | @Insert(onConflict = OnConflictStrategy.REPLACE)
11 | suspend fun insertUser(user: User?)
12 |
13 | @Update(onConflict = OnConflictStrategy.REPLACE)
14 | suspend fun updateUser(user: User?)
15 |
16 | @Query("DELETE FROM user_profile WHERE id=:id")
17 | suspend fun deleteUser(id: Int)
18 |
19 | @Query("SELECT * FROM user_profile WHERE id=:id ")
20 | fun getUser(id: Int): LiveData
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/db/ContestsDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.db
2 |
3 | import android.content.Context
4 | import androidx.room.Database
5 | import androidx.room.Room
6 | import androidx.room.RoomDatabase
7 | import com.cdhiraj40.leetdroid.data.dao.ContestDao
8 | import com.cdhiraj40.leetdroid.data.entitiy.Contest
9 |
10 | @Database(entities = [Contest::class], version = 5)
11 | abstract class ContestsDatabase : RoomDatabase() {
12 |
13 | abstract fun contestDao(): ContestDao
14 |
15 | companion object {
16 | private var INSTANCE: ContestsDatabase? = null
17 | fun getInstance(context: Context): ContestsDatabase {
18 | if (INSTANCE == null) {
19 | INSTANCE = Room.databaseBuilder(
20 | context.applicationContext,
21 | ContestsDatabase::class.java,
22 | "contests.db"
23 | )
24 | .fallbackToDestructiveMigration()
25 | .build()
26 | }
27 | return INSTANCE!!
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/db/DailyQuestionDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.db
2 |
3 | import android.content.Context
4 | import androidx.room.Database
5 |
6 | import androidx.room.Room
7 | import androidx.room.RoomDatabase
8 | import com.cdhiraj40.leetdroid.data.dao.DailyQuestionDao
9 | import com.cdhiraj40.leetdroid.data.entitiy.DailyQuestion
10 |
11 | @Database(entities = [DailyQuestion::class], version = 2)
12 | abstract class DailyQuestionDatabase : RoomDatabase() {
13 |
14 | abstract fun dailyQuestionDao(): DailyQuestionDao
15 |
16 | companion object {
17 | private var INSTANCE: DailyQuestionDatabase? = null
18 | fun getInstance(context: Context): DailyQuestionDatabase {
19 | if (INSTANCE == null) {
20 | INSTANCE = Room.databaseBuilder(
21 | context.applicationContext,
22 | DailyQuestionDatabase::class.java,
23 | "daily_question.db"
24 | )
25 | .fallbackToDestructiveMigration()
26 | .build()
27 | }
28 | return INSTANCE!!
29 | }
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/db/FirebaseUserDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.db
2 |
3 | import android.content.Context
4 | import androidx.room.Database
5 | import androidx.room.Room
6 | import androidx.room.RoomDatabase
7 | import com.cdhiraj40.leetdroid.data.dao.FirebaseUserDao
8 | import com.cdhiraj40.leetdroid.data.entitiy.FirebaseUserProfile
9 |
10 | @Database(entities = [FirebaseUserProfile::class], version = 1)
11 | abstract class FirebaseUserDatabase : RoomDatabase() {
12 |
13 | abstract fun firebaseUserDao(): FirebaseUserDao
14 |
15 | companion object {
16 | private var INSTANCE: FirebaseUserDatabase? = null
17 | fun getInstance(context: Context): FirebaseUserDatabase {
18 | if (INSTANCE == null) {
19 | INSTANCE = Room.databaseBuilder(
20 | context.applicationContext,
21 | FirebaseUserDatabase::class.java,
22 | "firebase_user.db"
23 | )
24 | .fallbackToDestructiveMigration()
25 | .build()
26 | }
27 | return INSTANCE!!
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/db/QuestionDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.db
2 |
3 | import android.content.Context
4 | import androidx.room.Database
5 |
6 | import androidx.room.Room
7 | import androidx.room.RoomDatabase
8 |
9 | import com.cdhiraj40.leetdroid.data.dao.QuestionsDao
10 | import com.cdhiraj40.leetdroid.data.entitiy.AllQuestions
11 |
12 | @Database(entities = [AllQuestions::class], version = 3)
13 | abstract class QuestionDatabase : RoomDatabase() {
14 |
15 | abstract fun questionsDao(): QuestionsDao
16 |
17 | companion object {
18 | private var INSTANCE: QuestionDatabase? = null
19 | fun getInstance(context: Context): QuestionDatabase {
20 | if (INSTANCE == null) {
21 | INSTANCE = Room.databaseBuilder(
22 | context.applicationContext,
23 | QuestionDatabase::class.java,
24 | "question.db"
25 | )
26 | .fallbackToDestructiveMigration()
27 | .build()
28 | }
29 | return INSTANCE!!
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/db/UserDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.db
2 |
3 | import android.content.Context
4 | import androidx.room.Database
5 |
6 | import androidx.room.Room
7 | import androidx.room.RoomDatabase
8 | import com.cdhiraj40.leetdroid.data.dao.UserDao
9 |
10 | import com.cdhiraj40.leetdroid.data.entitiy.User
11 |
12 | @Database(entities = [User::class], version = 5)
13 | abstract class UserDatabase : RoomDatabase() {
14 |
15 | abstract fun userDao(): UserDao
16 |
17 | companion object {
18 | private var INSTANCE: UserDatabase? = null
19 | fun getInstance(context: Context): UserDatabase {
20 | if (INSTANCE == null) {
21 | INSTANCE = Room.databaseBuilder(
22 | context.applicationContext,
23 | UserDatabase::class.java,
24 | "user_profile.db"
25 | )
26 | .fallbackToDestructiveMigration()
27 | .build()
28 | }
29 | return INSTANCE!!
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/entitiy/AllQuestions.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.entitiy
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.PrimaryKey
6 | import androidx.room.TypeConverters
7 | import com.cdhiraj40.leetdroid.utils.Constant
8 | import com.cdhiraj40.leetdroid.utils.Converters
9 |
10 | @Entity(tableName = "all_questions")
11 | @TypeConverters(Converters.DifficultyEnumConverters::class)
12 | data class AllQuestions(
13 | @ColumnInfo(name = "acRate")
14 | val acRate: Double,
15 | @ColumnInfo(name = "difficulty")
16 | val difficulty: Constant.DIFFICULTY, //enum converter
17 | @ColumnInfo(name = "frontendQuestionId")
18 | val frontendQuestionId: String,
19 | @ColumnInfo(name = "paidOnly")
20 | val paidOnly: Boolean,
21 | @ColumnInfo(name = "title")
22 | val title: String,
23 | @ColumnInfo(name = "titleSlug")
24 | val titleSlug: String,
25 | @ColumnInfo(name = "hasSolution")
26 | val hasSolution: Boolean,
27 | ) {
28 | @PrimaryKey(autoGenerate = true)
29 | var id: Int = 0
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/entitiy/Contest.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.entitiy
2 |
3 | import androidx.room.*
4 |
5 | @Entity(tableName = "contests")
6 | data class Contest(
7 | @ColumnInfo(name = "name")
8 | val name: String,
9 | @ColumnInfo(name = "url")
10 | val url: String,
11 | @ColumnInfo(name = "duration")
12 | val duration: String,
13 | @ColumnInfo(name = "start_time")
14 | val start_time: String,
15 | @ColumnInfo(name = "end_time")
16 | val end_time: String,
17 | @ColumnInfo(name = "in_24_hours")
18 | val in_24_hours: String,
19 | @ColumnInfo(name = "status")
20 | val status: String
21 | ) {
22 | @PrimaryKey(autoGenerate = true)
23 | var id: Int = 0
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/entitiy/DailyQuestion.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.entitiy
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.PrimaryKey
6 | import androidx.room.TypeConverters
7 | import com.cdhiraj40.leetdroid.utils.Converters
8 |
9 | @TypeConverters(
10 | Converters.DailyQuestionConverter::class,
11 | Converters.DailyQuestionDailyConverter::class,
12 | Converters.DailyQuestionTagsConverter::class
13 | )
14 | @Entity(tableName = "daily_question")
15 | data class DailyQuestion(
16 | @ColumnInfo(name = "activeDailyCodingChallengeQuestion")
17 | val activeDailyCodingChallengeQuestion: String,
18 |
19 | @ColumnInfo(name = "question")
20 | val question: String,
21 |
22 | @ColumnInfo(name = "topicTags")
23 | val topicTags: String,
24 | ) {
25 | @PrimaryKey(autoGenerate = true)
26 | var id: Int = 0
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/entitiy/FirebaseUserProfile.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.entitiy
2 |
3 | import androidx.room.ColumnInfo
4 | import androidx.room.Entity
5 | import androidx.room.PrimaryKey
6 |
7 | @Entity(tableName = "firebase_user")
8 | data class FirebaseUserProfile(
9 | @ColumnInfo(name = "uuid")
10 | val uuid: String,
11 | @ColumnInfo(name = "email")
12 | val email: String,
13 | @ColumnInfo(name = "username")
14 | val username: String,
15 | ) {
16 | @PrimaryKey(autoGenerate = true)
17 | var id: Int = 0
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/entitiy/User.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.entitiy
2 |
3 | import androidx.room.*
4 | import com.cdhiraj40.leetdroid.utils.Converters
5 |
6 | @Entity(tableName = "user_profile")
7 | @TypeConverters(
8 | Converters.ArrayListConverters::class,
9 | Converters.MatchedUserNodeConverters::class,
10 | Converters.SubmitStatsNodeConverters::class,
11 | Converters.ContributionsNodeConverters::class,
12 | Converters.ProfileNodeConverters::class,
13 | Converters.AllQuestionsCountConverters::class
14 | )
15 | data class User(
16 | @ColumnInfo(name = "allQuestionsCount")
17 | val allQuestionsCount: String,
18 | @ColumnInfo(name = "matchedUser")
19 | val matchedUser: String,
20 | @ColumnInfo(name = "contributions")
21 | val contributions: String,
22 | @ColumnInfo(name = "profile")
23 | val profile: String,
24 | @ColumnInfo(name = "acSubmissionNum")
25 | val acSubmissionNum: String,
26 | @ColumnInfo(name = "totalSubmissionNum")
27 | val totalSubmissionNum: String
28 | ) {
29 | @PrimaryKey(autoGenerate = true)
30 | var id: Int = 0
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/repository/ContestRepository.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.repository
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.cdhiraj40.leetdroid.data.dao.ContestDao
5 | import com.cdhiraj40.leetdroid.data.entitiy.Contest
6 |
7 | class ContestRepository(private val contestDao: ContestDao) {
8 |
9 | val allContest: LiveData> = contestDao.getAllContest()
10 |
11 | suspend fun insertContest(contest: Contest):Long =
12 | contestDao.insertContest(contest)
13 |
14 | suspend fun updateContest(contest: Contest) =
15 | contestDao.updateContest(contest)
16 |
17 | suspend fun deleteContest(id: Int) =
18 | contestDao.deleteContest(id)
19 |
20 | suspend fun getContest(id: Int):Contest =
21 | contestDao.getContest(id)
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/repository/DailyQuestionRepository.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.repository
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.cdhiraj40.leetdroid.data.dao.DailyQuestionDao
5 | import com.cdhiraj40.leetdroid.data.entitiy.DailyQuestion
6 |
7 | class DailyQuestionRepository(private val dailyQuestionDao: DailyQuestionDao) {
8 |
9 | val todaysQuestion = fun(id: Int): LiveData = dailyQuestionDao.getQuestion(id)
10 |
11 | suspend fun insertQuestion(question: DailyQuestion) =
12 | dailyQuestionDao.insertQuestion(question)
13 |
14 | suspend fun updateQuestion(question: DailyQuestion) =
15 | dailyQuestionDao.updateQuestion(question)
16 |
17 | suspend fun deleteQuestion(id: Int) =
18 | dailyQuestionDao.deleteQuestion(id)
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/repository/FirebaseUserRepository.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.repository
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.cdhiraj40.leetdroid.data.dao.FirebaseUserDao
5 | import com.cdhiraj40.leetdroid.data.entitiy.FirebaseUserProfile
6 |
7 | class FirebaseUserRepository(private val firebaseUserDao: FirebaseUserDao) {
8 |
9 | val firebaseUser = fun(id: Int): LiveData = firebaseUserDao.getUser(id)
10 |
11 | suspend fun insertUser(firebaseUser: FirebaseUserProfile) =
12 | firebaseUserDao.insertUser(firebaseUser)
13 |
14 | suspend fun updateUser(firebaseUser: FirebaseUserProfile) =
15 | firebaseUserDao.updateUser(firebaseUser)
16 |
17 | suspend fun deleteUser(id: Int) =
18 | firebaseUserDao.deleteUser(id)
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/repository/UserRepository.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.repository
2 |
3 | import androidx.lifecycle.LiveData
4 | import com.cdhiraj40.leetdroid.data.dao.UserDao
5 | import com.cdhiraj40.leetdroid.data.entitiy.User
6 |
7 | class UserRepository(private val userDao: UserDao) {
8 |
9 | val user = fun(id: Int): LiveData = userDao.getUser(id)
10 |
11 | suspend fun insertUser(user: User) =
12 | userDao.insertUser(user)
13 |
14 | suspend fun updateUser(user: User) =
15 | userDao.updateUser(user)
16 |
17 | suspend fun deleteUser(id: Int) =
18 | userDao.deleteUser(id)
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/viewModel/ConnectionLiveData.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.viewModel
2 |
3 | import android.content.Context
4 | import android.content.Context.CONNECTIVITY_SERVICE
5 | import android.net.ConnectivityManager
6 | import android.net.Network
7 | import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
8 | import android.net.NetworkRequest
9 | import android.util.Log
10 | import androidx.lifecycle.LiveData
11 | import kotlinx.coroutines.CoroutineScope
12 | import kotlinx.coroutines.Dispatchers
13 | import kotlinx.coroutines.launch
14 | import kotlinx.coroutines.withContext
15 | import java.io.IOException
16 | import java.net.InetSocketAddress
17 | import javax.net.SocketFactory
18 |
19 | const val TAG = "MyTagConnectionManager"
20 |
21 | class ConnectionLiveData(context: Context) : LiveData() {
22 |
23 | private lateinit var networkCallback: ConnectivityManager.NetworkCallback
24 | private val connectivityManager =
25 | context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
26 | private val validNetworks: MutableSet = HashSet()
27 |
28 | private fun checkValidNetworks() {
29 | postValue(validNetworks.size > 0)
30 | }
31 |
32 | override fun onActive() {
33 | networkCallback = createNetworkCallback()
34 | val networkRequest = NetworkRequest.Builder()
35 | .addCapability(NET_CAPABILITY_INTERNET)
36 | .build()
37 | connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
38 | }
39 |
40 | override fun onInactive() {
41 | connectivityManager.unregisterNetworkCallback(networkCallback)
42 | }
43 |
44 | private fun createNetworkCallback() = object : ConnectivityManager.NetworkCallback() {
45 |
46 | override fun onAvailable(network: Network) {
47 | Log.d(TAG, "onAvailable: $network")
48 | val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
49 | val hasInternetCapability = networkCapabilities?.hasCapability(NET_CAPABILITY_INTERNET)
50 | Log.d(TAG, "onAvailable: ${network}, $hasInternetCapability")
51 |
52 | if (hasInternetCapability == true) {
53 | // Check if this network actually has internet
54 | CoroutineScope(Dispatchers.IO).launch {
55 | val hasInternet = DoesNetworkHaveInternet.execute(network.socketFactory)
56 | if (hasInternet) {
57 | withContext(Dispatchers.Main) {
58 | Log.d(TAG, "onAvailable: adding network. $network")
59 | validNetworks.add(network)
60 | checkValidNetworks()
61 | }
62 | }
63 | }
64 | }
65 | }
66 |
67 | override fun onLost(network: Network) {
68 | Log.d(TAG, "onLost: $network")
69 | validNetworks.remove(network)
70 | checkValidNetworks()
71 | }
72 | }
73 |
74 | object DoesNetworkHaveInternet {
75 |
76 | fun execute(socketFactory: SocketFactory): Boolean {
77 | // Make sure to execute this on a background thread.
78 | return try {
79 | Log.d(TAG, "PINGING Google...")
80 | val socket = socketFactory.createSocket() ?: throw IOException("Socket is null.")
81 | socket.connect(InetSocketAddress("8.8.8.8", 53), 1500)
82 | socket.close()
83 | Log.d(TAG, "PING success.")
84 | true
85 | } catch (e: IOException) {
86 | Log.e(TAG, "No Internet Connection. $e")
87 | false
88 | }
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/viewModel/ContestViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.viewModel
2 |
3 | import android.app.Application
4 | import androidx.lifecycle.AndroidViewModel
5 | import androidx.lifecycle.LiveData
6 | import androidx.lifecycle.viewModelScope
7 | import com.cdhiraj40.leetdroid.data.db.ContestsDatabase
8 | import com.cdhiraj40.leetdroid.data.entitiy.Contest
9 | import com.cdhiraj40.leetdroid.data.repository.ContestRepository
10 | import kotlinx.coroutines.Dispatchers
11 | import kotlinx.coroutines.launch
12 |
13 | class ContestViewModel(application: Application) : AndroidViewModel(application) {
14 |
15 | private val contestRepository: ContestRepository
16 | val getAllContest: LiveData>
17 |
18 | init {
19 | val contestDB = ContestsDatabase.getInstance(application).contestDao()
20 | contestRepository = ContestRepository(contestDB)
21 | getAllContest = contestRepository.allContest
22 | }
23 |
24 | fun addContest(contest: Contest) {
25 | viewModelScope.launch(Dispatchers.IO) {
26 | contestRepository.insertContest(contest)
27 | }
28 | }
29 |
30 | fun updateContest(contest: Contest) {
31 | viewModelScope.launch(Dispatchers.IO) {
32 | contestRepository.updateContest(contest)
33 | }
34 | }
35 |
36 | fun deleteContest(id: Int) {
37 | viewModelScope.launch(Dispatchers.IO) {
38 | contestRepository.deleteContest(id)
39 | }
40 | }
41 |
42 | suspend fun getContest(id: Int): Contest {
43 | viewModelScope.launch(Dispatchers.IO) {
44 | contestRepository.getContest(id)
45 | }
46 | return contestRepository.getContest(id)
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/viewModel/DailyQuestionViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.viewModel
2 |
3 | import android.app.Application
4 | import androidx.lifecycle.AndroidViewModel
5 | import androidx.lifecycle.LiveData
6 | import androidx.lifecycle.viewModelScope
7 | import com.cdhiraj40.leetdroid.data.db.DailyQuestionDatabase
8 |
9 | import com.cdhiraj40.leetdroid.data.entitiy.DailyQuestion
10 |
11 | import com.cdhiraj40.leetdroid.data.repository.DailyQuestionRepository
12 |
13 | import kotlinx.coroutines.Dispatchers
14 | import kotlinx.coroutines.launch
15 |
16 | class DailyQuestionViewModel(application: Application) : AndroidViewModel(application) {
17 |
18 | private val dailyQuestionRepository: DailyQuestionRepository
19 | val dailyQuestion: LiveData
20 |
21 | init {
22 | val questionDB = DailyQuestionDatabase.getInstance(application).dailyQuestionDao()
23 | dailyQuestionRepository = DailyQuestionRepository(questionDB)
24 | dailyQuestion = dailyQuestionRepository.todaysQuestion(1)
25 | }
26 |
27 | fun addQuestion(question: DailyQuestion) {
28 | viewModelScope.launch(Dispatchers.IO) {
29 | dailyQuestionRepository.insertQuestion(question)
30 | }
31 | }
32 |
33 | fun updateQuestion(question: DailyQuestion) {
34 | viewModelScope.launch(Dispatchers.IO) {
35 | dailyQuestionRepository.updateQuestion(question)
36 | }
37 | }
38 |
39 | fun deleteQuestion(id: Int) {
40 | viewModelScope.launch(Dispatchers.IO) {
41 | dailyQuestionRepository.deleteQuestion(id)
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/viewModel/FirebaseUserViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.viewModel
2 |
3 | import android.app.Application
4 | import androidx.lifecycle.AndroidViewModel
5 | import androidx.lifecycle.LiveData
6 | import androidx.lifecycle.viewModelScope
7 | import com.cdhiraj40.leetdroid.data.db.FirebaseUserDatabase
8 | import com.cdhiraj40.leetdroid.data.entitiy.FirebaseUserProfile
9 | import com.cdhiraj40.leetdroid.data.repository.FirebaseUserRepository
10 | import kotlinx.coroutines.Dispatchers
11 | import kotlinx.coroutines.launch
12 |
13 | class FirebaseUserViewModel(application: Application) : AndroidViewModel(application) {
14 |
15 | private val firebaseUserRepository: FirebaseUserRepository
16 | val getFirebaseUser: LiveData
17 |
18 | init {
19 | val firebaseUserDB = FirebaseUserDatabase.getInstance(application).firebaseUserDao()
20 | firebaseUserRepository = FirebaseUserRepository(firebaseUserDB)
21 | getFirebaseUser = firebaseUserRepository.firebaseUser(1)
22 | }
23 |
24 | fun addUser(firebaseUser: FirebaseUserProfile) {
25 | viewModelScope.launch(Dispatchers.IO) {
26 | firebaseUserRepository.insertUser(firebaseUser)
27 | }
28 | }
29 |
30 | fun updateUser(firebaseUser: FirebaseUserProfile) {
31 | viewModelScope.launch(Dispatchers.IO) {
32 | firebaseUserRepository.updateUser(firebaseUser)
33 | }
34 | }
35 |
36 | fun deleteUser(id: Int) {
37 | viewModelScope.launch(Dispatchers.IO) {
38 | firebaseUserRepository.deleteUser(id)
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/data/viewModel/UserViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.data.viewModel
2 |
3 | import android.app.Application
4 | import androidx.lifecycle.AndroidViewModel
5 | import androidx.lifecycle.LiveData
6 | import androidx.lifecycle.viewModelScope
7 |
8 | import com.cdhiraj40.leetdroid.data.db.UserDatabase
9 | import com.cdhiraj40.leetdroid.data.entitiy.User
10 | import com.cdhiraj40.leetdroid.data.repository.UserRepository
11 | import kotlinx.coroutines.Dispatchers
12 | import kotlinx.coroutines.launch
13 |
14 | class UserViewModel(application: Application) : AndroidViewModel(application) {
15 |
16 | private val userRepository: UserRepository
17 | val getUser: LiveData
18 |
19 | init {
20 | val userDB = UserDatabase.getInstance(application).userDao()
21 | userRepository = UserRepository(userDB)
22 | getUser = userRepository.user(1)
23 | }
24 |
25 | fun addUser(user: User) {
26 | viewModelScope.launch(Dispatchers.IO) {
27 | userRepository.insertUser(user)
28 | }
29 | }
30 |
31 | fun updateUser(user: User) {
32 | viewModelScope.launch(Dispatchers.IO) {
33 | userRepository.updateUser(user)
34 | }
35 | }
36 |
37 | fun deleteUser(id: Int) {
38 | viewModelScope.launch(Dispatchers.IO) {
39 | userRepository.deleteUser(id)
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/AllQuestionsErrorModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Data Model for the all questions list' error
7 | * if no data comes we check for error here
8 | */
9 | class AllQuestionsErrorModel : Serializable {
10 |
11 |
12 | /**
13 | * "errors": [ "message": "2", "locations": [ { "line": 1, "column": 115 } ], "path": [ "problemsetQuestionList" ] } ], "data": { "problemsetQuestionList": null } }
14 | */
15 | var errors: List? = null
16 |
17 | class ErrorsNode : Serializable {
18 | /**
19 | * "message": "2", "locations": [ { "line": 1, "column": 115 } ], "path": [ "problemsetQuestionList" ] } ], "data": { "problemsetQuestionList": null } }
20 | */
21 |
22 | var message: String? = null
23 | var locations: List? = null
24 |
25 | class LocationsNode : Serializable {
26 | var line: Int? = null
27 | var column: Int? = null
28 | var path: List? = null
29 | }
30 | }
31 |
32 | var data: DataNode? = null
33 |
34 | class DataNode : Serializable {
35 | var problemsetQuestionList: ProblemSetQuestionListNode? = null
36 |
37 | class ProblemSetQuestionListNode : Serializable {
38 |
39 | var total: Int = 0
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/AllQuestionsModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Data Model for the all questions list
7 | */
8 | class AllQuestionsModel : Serializable {
9 | /**
10 | * data: { "problemsetQuestionList": {"total": 2137,
11 | * "questions": [
12 | * { "acRate": 48.10413384552075, "difficulty": "Easy", "frontendQuestionId": "1", "paidOnly": false, "title": "Two Sum", "titleSlug": "two-sum", "topicTags": [ { "name": "Array", "id": "VG9waWNUYWdOb2RlOjU=",
13 | * "slug": "array"},{"name": "Hash Table","id": "VG9waWNUYWdOb2RlOjY=","slug": "hash-table" } ] } ] } } }
14 | */
15 | var data: DataNode? = null
16 |
17 | class DataNode : Serializable {
18 | /**
19 | * problemsetQuestionList: {"total": 2137,"questions": [ { "acRate": 48.10413384552075, "difficulty": "Easy", "frontendQuestionId": "1", "paidOnly": false, "title": "Two Sum",
20 | * "titleSlug": "two-sum", "topicTags": [ { "name": "Array", "id": "VG9waWNUYWdOb2RlOjU=","slug": "array"},{"name": "Hash Table","id": "VG9waWNUYWdOb2RlOjY=","slug": "hash-table" } ]
21 | * "hasSolution": true } ] } } }
22 | */
23 | var problemsetQuestionList: ProblemSetQuestionListNode? = null
24 |
25 | class ProblemSetQuestionListNode : Serializable {
26 |
27 | var total: Int = 0
28 | var questions: List? = null
29 |
30 | class Questions : Serializable {
31 |
32 | var title: String? = null
33 | var titleSlug: String? = null
34 | var difficulty: String? = null
35 | var acRate: Double? = null
36 | var paidOnly: Boolean? = null
37 | var frontendQuestionId: String? = null
38 | var topicTags: List? = null
39 |
40 | class TopicTagsNode : Serializable {
41 |
42 | /**
43 | * topicTags: [ { "name": "Array", "id": "VG9waWNUYWdOb2RlOjU=","slug": "array"},{"name": "Hash Table","id": "VG9waWNUYWdOb2RlOjY=","slug": "hash-table" } ] } ] } } }
44 | */
45 |
46 | var name: String? = null
47 | var id: String? = null
48 | var slug: String? = null
49 | }
50 |
51 | var hasSolution: Boolean? = null
52 | }
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/ContestRankingModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | class ContestRankingModel : Serializable {
6 | /**
7 | * data : "userContestRanking": { "attendedContestsCount": 1, "rating": 1465.221, "globalRanking": 131082 },
8 | * "userContestRankingHistory": [ { "contest": { "title": "Weekly Contest 2", "startTime": 1472347800 }, "rating": 1500.0, "ranking": 0 } ] }
9 | */
10 | var data: DataNode? = null
11 |
12 | class DataNode : Serializable {
13 | var userContestRanking: UserContestRankingNode? = null
14 |
15 | class UserContestRankingNode : Serializable {
16 | var attendedContestsCount: Int? = null
17 | var rating: Double? = null
18 | var globalRanking: Long? = null
19 | }
20 |
21 | var userContestRankingHistory: List? = null
22 |
23 | class UserContestRankingHistoryNode : Serializable {
24 | var contest: ContestNode? = null
25 | var rating: Double? = null
26 | var ranking: Long? = null
27 |
28 | class ContestNode {
29 | var title: String? = null
30 | var startTime: Long? = null
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/ContestsModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | data class ContestsModel(
4 | val name: String,
5 | val url:String,
6 | val duration: String,
7 | val start_time: String,
8 | val end_time: String,
9 | val in_24_hours: String,
10 | val status: String
11 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/ContributorListModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | class ContributorListModel : ArrayList() {
4 |
5 | val contributorListItem: ContributorListModelItem? = null
6 |
7 | class ContributorListModelItem {
8 | val author: AuthorNode? = null
9 |
10 | class AuthorNode {
11 | val id: Int? = null
12 | val login: String? = null
13 | val avatar_url: String? = null
14 | val html_url: String? = null
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/DailyQuestionModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Data Model for the all questions list
7 | */
8 | class DailyQuestionModel : Serializable {
9 |
10 |
11 | /**
12 | * data : { "activeDailyCodingChallengeQuestion": { "date": "2022-01-30", "userStatus": "NotStart", "link": "/problems/rotate-array/",
13 | * "question": { "acRate": 38.02651800583092, "difficulty": "Medium", "freqBar": null, "frontendQuestionId": "189", "isFavor": false,
14 | * "paidOnly": false, "status": null, "title": "Rotate Array", "titleSlug": "rotate-array", "hasVideoSolution": false, "hasSolution": true,
15 | * "topicTags": [ { "name": "Array", "id": "VG9waWNUYWdOb2RlOjU=", "slug": "array" }, { "name": "Math", "id": "VG9waWNUYWdOb2RlOjg=", "slug": "math" },
16 | * { "name": "Two Pointers", "id": "VG9waWNUYWdOb2RlOjk=", "slug": "two-pointers" } ] } } } }
17 | */
18 | var data: DataNode? = null
19 |
20 | class DataNode : Serializable {
21 | /**
22 | * "activeDailyCodingChallengeQuestion": { "date": "2022-01-30", "link": "/problems/rotate-array/","question": { "acRate": 38.02651800583092, difficulty": "Medium",
23 | * "frontendQuestionId": "189","paidOnly": false, "title": "Rotate Array","titleSlug": "rotate-array", "hasVideoSolution": false, "hasSolution": true,
24 | * "topicTags": [ { "name": "Array", "id": "VG9waWNUYWdOb2RlOjU=", "slug": "array" }, { "name": "Math", "id": "VG9waWNUYWdOb2RlOjg=", "slug": "math" },{ "name": "Two Pointers",
25 | * "id": "VG9waWNUYWdOb2RlOjk=", "slug": "two-pointers" } ] } } } }
26 | */
27 |
28 | var activeDailyCodingChallengeQuestion: ActiveDailyCodingChallengeQuestionNode? = null
29 |
30 | class ActiveDailyCodingChallengeQuestionNode : Serializable {
31 |
32 | var date: String? = null
33 | var link: String? = null
34 | var question: QuestionNode? = null
35 |
36 | class QuestionNode : Serializable {
37 |
38 | var title: String? = null
39 | var titleSlug: String? = null
40 | var difficulty: String? = null
41 | var acRate: Float? = null
42 | var paidOnly: Boolean? = null
43 | var frontendQuestionId: String? = null
44 | var hasVideoSolution: Boolean? = null
45 | var hasSolution: Boolean? = null
46 | var topicTags: List? = null
47 |
48 | class TopicTagsNode : Serializable {
49 |
50 | /**
51 | * topicTags: [ { "name": "Array", "id": "VG9waWNUYWdOb2RlOjU=","slug": "array"},{"name": "Hash Table","id": "VG9waWNUYWdOb2RlOjY=","slug": "hash-table" } ] } ] } } }
52 | */
53 |
54 | var name: String? = null
55 | var id: String? = null
56 | var slug: String? = null
57 | }
58 |
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/FirebaseUserModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | data class FirebaseUserModel(
4 | var uuid: String = "",
5 | var email: String = "",
6 | var username: String = "",
7 | )
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/LicensesModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Data Model for the all questions list' error
7 | * if no data comes we check for error here
8 | */
9 | class LicensesModel : Serializable {
10 |
11 | /**
12 | *
13 | * { "libraries": { "library": [ { "name": "LeetDroid", "author": "Dhiraj Chauhan", "website": "https://github.com/cdhiraj40/LeetDroid/", "license": "MIT License" },
14 | * { "name": "Android Jetpack", "author": "Google", "website": "https://developer.android.com/jetpack", "license": "Apache 2.0 License" },
15 | */
16 | var libraries: LibrariesNode? = null
17 |
18 | class LibrariesNode {
19 | var library: List? = null
20 |
21 | class Library {
22 | var name: String? = null
23 | var author: String? = null
24 | var website: String? = null
25 | var license: String? = null
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/QuestionSolutionModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | class QuestionSolutionModel : Serializable {
6 | /**
7 | * data: { "question": { "questionId": "1", "article": "{\"id\": 7, \"url\": \"/articles/two-sum/\", \"topicId\": 127810}", "solution": { "id": "7", "content":"content", "contentTypeId": "107",
8 | * "canSeeDetail": true, "paidOnly": false, "hasVideoSolution": true, "paidOnlyVideo": true, "rating": { "id": "4", "count": 2794, "average": "4.730" } } } } }
9 | */
10 | var data: DataNode? = null
11 |
12 | class DataNode : Serializable {
13 | var question: QuestionNode? = null
14 |
15 | class QuestionNode : Serializable {
16 | var questionId: String? = null
17 | var article: String? = null
18 | var solution: SolutionNode? = null
19 |
20 | class SolutionNode : Serializable {
21 | var id: String? = null
22 | var content: String? = null
23 | var contentTypeId: String? = null
24 | var canSeeDetail: Boolean? = null
25 | var paidOnly: Boolean? = null
26 | var hasVideoSolution: Boolean? = null
27 | var paidOnlyVideo: Boolean? = null
28 | var rating: RatingNode? = null
29 |
30 | class RatingNode : Serializable {
31 | var id: String? = null
32 | var count: Int? = null
33 | var average: String? = null
34 | }
35 | }
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/RandomQuestionModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | class RandomQuestionModel : Serializable {
6 | /**
7 | * data
8 | * randomQuestion": { "titleSlug": "zuma-game" } }
9 | */
10 | var data: DataNode? = null
11 |
12 | class DataNode : Serializable {
13 | var randomQuestion: RandomQuestionNode? = null
14 |
15 | class RandomQuestionNode : Serializable {
16 | var titleSlug: String? = null
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/TrendingDiscussionModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Data Model for the all questions list' error
7 | * if no data comes we check for error here
8 | */
9 | class TrendingDiscussionModel : Serializable {
10 |
11 | var data: DataNode? = null
12 |
13 | class DataNode : Serializable {
14 | var cachedTrendingCategoryTopics: List? = null
15 |
16 | class CachedTrendingCategoryTopics : Serializable {
17 | val id: Int? = null
18 | val post: PostNode? = null
19 | val title: String? = null
20 |
21 | class PostNode : Serializable {
22 | val author: AuthorNode? = null
23 | val contentPreview: String? = null
24 | val creationDate: Int? = null
25 | val id: Int? = null
26 |
27 | class AuthorNode : Serializable {
28 | val isActive: Boolean? = null
29 | val profile: ProfileNode? = null
30 | val username: String? = null
31 |
32 | class ProfileNode : Serializable {
33 | val userAvatar: String? = null
34 | }
35 | }
36 | }
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/model/UserProfileErrorModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.model
2 |
3 | import java.io.Serializable
4 |
5 | class UserProfileErrorModel : Serializable {
6 |
7 | /**
8 | errors : [ { "message": "That user does not exist.", "locations": [ { "line": 6, "column": 3 } ],}
9 | */
10 | var errors: List? = null
11 |
12 | class ErrorNode : Serializable {
13 |
14 | val message: String? = null
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/notification/DailyQuestionAlarmReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.notification
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.util.Log
7 |
8 | class DailyQuestionAlarmReceiver : BroadcastReceiver() {
9 | // TODO check what was the exception
10 | override fun onReceive(context: Context, intent: Intent) {
11 | try {
12 | Notification.showNotification(
13 | context,
14 | "Daily Challenge has been updated",
15 | "Lets complete this one too.",
16 | "daily_question",
17 | "daily_question_channel",
18 | 105
19 |
20 | )
21 | } catch (ex: Exception) {
22 | Log.d("Receive Ex", "onReceive: ${ex.printStackTrace()}")
23 | }
24 | }
25 | }
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/notification/DayContestAlarmReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.notification
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.util.Log
7 |
8 | class DayContestAlarmReceiver : BroadcastReceiver() {
9 | // TODO check what was the exception
10 | var alarmName: String? = null
11 | override fun onReceive(context: Context, intent: Intent) {
12 | try {
13 | Notification.showNotification(
14 | context,
15 | alarmName!!,
16 | "There is only a day remaining to $alarmName register now!",
17 | "contest_reminder_1day_weekly",
18 | "contest_reminder_1day_weekly_channel",
19 | 101
20 | )
21 |
22 | } catch (ex: Exception) {
23 | Log.d("Receive Ex", "onReceive: ${ex.printStackTrace()}")
24 | }
25 | }
26 | }
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/notification/MinContestAlarmReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.notification
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.util.Log
7 |
8 | class MinContestAlarmReceiver : BroadcastReceiver() {
9 | // TODO check what was the exception
10 | var alarmName: String? = null
11 | override fun onReceive(context: Context, intent: Intent) {
12 | try {
13 | Notification.showNotification(
14 | context,
15 | alarmName!!,
16 | "There is only 30 mins remaining to $alarmName register now!",
17 | "contest_reminder_30_mins_biweekly",
18 | "contest_reminder_30_mins_biweekly_channel",
19 | 104
20 | )
21 | } catch (ex: Exception) {
22 | Log.d("Receive Ex", "onReceive: ${ex.printStackTrace()}")
23 | }
24 | }
25 | }
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/notification/Notification.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.notification
2 |
3 | import android.app.NotificationChannel
4 | import android.app.NotificationManager
5 | import android.app.PendingIntent
6 | import android.content.Context
7 | import android.content.Intent
8 | import android.os.Build
9 | import androidx.core.app.NotificationCompat
10 | import com.cdhiraj40.leetdroid.R
11 | import com.cdhiraj40.leetdroid.ui.base.MainActivity
12 |
13 | /**
14 | * Different Notification IDs
15 | * 101 -> Notification for a day before weekly contest
16 | * 102 -> Notification for a day before biweekly contest
17 | * 103 -> Notification for 30 minutes before weekly contest
18 | * 104 -> Notification for 30 minutes before biweekly contest
19 | * 105 -> Notification for new daily challenge
20 | */
21 | object Notification {
22 | fun showNotification(
23 | context: Context,
24 | title: String,
25 | desc: String,
26 | channelId: String,
27 | channelName: String,
28 | notificationId: Int
29 | ) {
30 | val notificationManager =
31 | context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
32 |
33 | val intent = Intent(context, MainActivity::class.java)
34 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
35 | val random = System.currentTimeMillis().toInt()
36 | val pendingIntent = PendingIntent.getActivity(context, random, intent, 0)
37 |
38 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
39 | val channel =
40 | NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)
41 | notificationManager.createNotificationChannel(channel)
42 | }
43 |
44 | val builder = NotificationCompat.Builder(context, channelId)
45 | // TODO change icon later with app logo
46 | .setSmallIcon(R.drawable.ic_baseline_discuss_24)
47 | .setContentTitle(title)
48 | .setStyle(NotificationCompat.BigTextStyle().bigText(desc))
49 | .setAutoCancel(true)
50 | .setDefaults(NotificationCompat.DEFAULT_ALL)
51 | .setPriority(NotificationCompat.PRIORITY_DEFAULT)
52 | .setContentIntent(pendingIntent)
53 |
54 | notificationManager.notify(notificationId, builder.build())
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/sharedViewModel/QuestionDiscussionSharedViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.sharedViewModel
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 |
6 | class QuestionDiscussionSharedViewModel : ViewModel() {
7 |
8 | val discussionTitle = MutableLiveData()
9 |
10 | // function to get question's discussion item title
11 | fun getDiscussionTitle(title: String) {
12 | discussionTitle.postValue(title)
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/sharedViewModel/QuestionSharedViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.sharedViewModel
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 |
6 | class QuestionSharedViewModel : ViewModel() {
7 |
8 | val questionTitleSlug = MutableLiveData()
9 | val questionTitle = MutableLiveData()
10 | val questionHasSolution = MutableLiveData()
11 | val questionID = MutableLiveData()
12 | val questionPaid = MutableLiveData()
13 |
14 |
15 | // function to get title slug
16 | fun getQuestionTitleSlug(titleSlug: String) {
17 | questionTitleSlug.postValue(titleSlug)
18 | }
19 |
20 | // function to get title
21 | fun getQuestionTitle(title: String) {
22 | questionTitle.postValue(title)
23 | }
24 |
25 | // function to get title slug
26 | fun getQuestionHasSolution(hasSolution: Boolean) {
27 | questionHasSolution.postValue(hasSolution)
28 | }
29 |
30 | // function to get question ID
31 | fun getQuestionId(questionId: String) {
32 | questionID.postValue(questionId)
33 | }
34 |
35 | // function to get question's status -> paid/free
36 | fun isQuestionPaid(status: Boolean) {
37 | questionPaid.postValue(status)
38 | }
39 |
40 | // function to get question's discussion item title
41 | fun getDiscussionTitle(status: Boolean) {
42 | questionPaid.postValue(status)
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/ui/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.ui.base
2 |
3 | import android.os.Bundle
4 | import androidx.fragment.app.Fragment
5 | import kotlinx.coroutines.CoroutineScope
6 | import kotlinx.coroutines.Dispatchers
7 | import kotlinx.coroutines.Job
8 | import kotlin.coroutines.CoroutineContext
9 |
10 | abstract class BaseFragment : Fragment(), CoroutineScope {
11 |
12 | private lateinit var job: Job
13 | override val coroutineContext: CoroutineContext
14 | get() = job + Dispatchers.Main
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 | job = Job()
19 | }
20 |
21 | override fun onDestroy() {
22 | super.onDestroy()
23 | job.cancel()
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/ui/fragments/preferences/AboutFragment.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.ui.fragments.preferences
2 |
3 | import android.os.Bundle
4 | import androidx.navigation.fragment.findNavController
5 | import androidx.preference.Preference
6 | import androidx.preference.PreferenceFragmentCompat
7 | import com.cdhiraj40.leetdroid.BuildConfig
8 | import com.cdhiraj40.leetdroid.R
9 | import com.cdhiraj40.leetdroid.utils.extensions.copyToClipboard
10 | import com.cdhiraj40.leetdroid.utils.extensions.showSnackBar
11 |
12 |
13 | class AboutFragment : PreferenceFragmentCompat() {
14 |
15 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
16 | setPreferencesFromResource(R.xml.preferences_about, rootKey)
17 |
18 |
19 | findPreference("about_version")!!.summary = String.format(
20 | "%s", BuildConfig.VERSION_NAME
21 | )
22 | findPreference("about_version")!!.setOnPreferenceClickListener { preference ->
23 | requireContext().copyToClipboard(
24 | findPreference("about_version")!!.summary.toString()
25 | )
26 | showSnackBar(requireActivity(), "Copied")
27 | true
28 | }
29 | findPreference("about_contributors")!!.setOnPreferenceClickListener { preference ->
30 | findNavController().navigate(R.id.contributorFragment)
31 | true
32 | }
33 | findPreference("about_licenses")!!.setOnPreferenceClickListener { preference ->
34 | findNavController().navigate(R.id.licensesFragment)
35 | true
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/ui/fragments/preferences/LicenseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.ui.fragments.preferences
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import androidx.recyclerview.widget.LinearLayoutManager
9 | import com.cdhiraj40.leetdroid.adapter.LicenseListAdapter
10 | import com.cdhiraj40.leetdroid.databinding.FragmentLicenseBinding
11 | import com.cdhiraj40.leetdroid.model.LicensesModel
12 | import com.cdhiraj40.leetdroid.utils.CommonUtils.openLink
13 | import com.cdhiraj40.leetdroid.utils.JsonUtils
14 | import com.cdhiraj40.leetdroid.utils.JsonUtils.readAssetsFile
15 |
16 | class LicenseFragment : Fragment(), LicenseListAdapter.OnItemClicked {
17 |
18 | private lateinit var licenseBinding: FragmentLicenseBinding
19 | private lateinit var licenseListAdapter: LicenseListAdapter
20 | override fun onCreateView(
21 | inflater: LayoutInflater, container: ViewGroup?,
22 | savedInstanceState: Bundle?
23 | ): View {
24 | // Inflate the layout for this fragment
25 | licenseBinding = FragmentLicenseBinding.inflate(inflater)
26 |
27 | val rootView = licenseBinding.root
28 | licenseListAdapter = LicenseListAdapter(requireContext())
29 | licenseListAdapter.setOnClick(this)
30 | setUpLicenses()
31 | return rootView
32 | }
33 |
34 | private fun setUpLicenses() {
35 | val licenseString = requireContext().assets.readAssetsFile("licenses.json")
36 |
37 | val licenseJson: LicensesModel = JsonUtils.generateObjectFromJson(
38 | licenseString,
39 | LicensesModel::class.java
40 | )
41 |
42 | licenseListAdapter.setData(licenseJson)
43 | licenseBinding.licenseRecyclerView.layoutManager =
44 | LinearLayoutManager(context)
45 | licenseBinding.licenseRecyclerView.adapter =
46 | licenseListAdapter
47 |
48 | }
49 |
50 | override fun onItemClick(position: Int, website: String?) {
51 | openLink(requireContext(), website.toString())
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/CommonFunctions.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.view.Menu
6 | import android.view.MenuItem
7 | import com.cdhiraj40.leetdroid.ui.authentication.LoginActivity
8 | import com.cdhiraj40.leetdroid.utils.dialog.AlertDialogShower
9 | import com.cdhiraj40.leetdroid.utils.dialog.AppDialogs
10 | import com.cdhiraj40.leetdroid.utils.extensions.openActivity
11 | import com.google.firebase.auth.FirebaseAuth
12 | import kotlin.math.pow
13 | import kotlin.math.roundToInt
14 |
15 |
16 | class CommonFunctions {
17 | object Logout {
18 | fun showLogOutDialog(activity: Activity, context: Context): Boolean {
19 | AlertDialogShower(activity).show(AppDialogs.Logout, {
20 | FirebaseAuth.getInstance().signOut()
21 | activity.openActivity(LoginActivity::class.java)
22 | activity.finish()
23 | return@show
24 | }, {
25 |
26 | })
27 | return false
28 | }
29 | }
30 |
31 | object Round {
32 | fun roundDouble(value: Double, precision: Int): Double {
33 | val scale = 10.0.pow(precision.toDouble()).toInt()
34 | return (value * scale).roundToInt().toDouble() / scale
35 | }
36 | }
37 |
38 | object MenuItemVisibility {
39 | fun setItemsVisibility(menu: Menu, exception: MenuItem, visible: Boolean) {
40 | for (i in 0 until menu.size()) {
41 | val item = menu.getItem(i)
42 | if (item !== exception) item.isVisible = visible
43 | }
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/Constant.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | class Constant {
4 |
5 | val userName = "cdhiraj40"
6 | val repositoryName = "LeetDroid"
7 |
8 | enum class DIFFICULTY(name: String) {
9 | Easy("Easy"),
10 | Medium("Medium"),
11 | Hard("Hard")
12 | }
13 |
14 | companion object {
15 | fun TAG(className: Class?): String? {
16 | return className?.name
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/DateUtils.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | import android.text.format.DateFormat
4 | import org.threeten.bp.DateTimeUtils.toDate
5 | import org.threeten.bp.Instant
6 | import org.threeten.bp.format.DateTimeFormatter
7 | import org.threeten.bp.temporal.TemporalAccessor
8 | import java.text.SimpleDateFormat
9 | import java.util.*
10 |
11 | object DateUtils {
12 |
13 | fun parseISO8601Date(date: String): Date {
14 | val temporalAccessor: TemporalAccessor = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(date)
15 | val instant = Instant.from(temporalAccessor)
16 | return formatISO8601Date(toDate(instant))
17 | }
18 |
19 | fun formatISO8601Date(date: Date): Date {
20 | val formatter = SimpleDateFormat("E MMM dd HH:mm:ss Z yyyy", Locale.getDefault())
21 | return formatter.parse(date.toString())!!
22 | }
23 |
24 | fun getDate(date: Date): String? {
25 | return SimpleDateFormat("MMM dd, yyyy", Locale.getDefault()).format(date)
26 | }
27 |
28 | fun getTime(date: Date?): String? {
29 | return SimpleDateFormat("HH:mm", Locale.getDefault()).format(date!!)
30 | }
31 |
32 | fun getHours(time: String): String {
33 | return (time.toInt() / 3600.0).toString()
34 | }
35 |
36 | fun getSeconds(time: String): Int {
37 | val actualTime = time.split(':')
38 | return actualTime[0].toInt() * 60 * 60 + (actualTime[1]).toInt() * 60
39 | }
40 |
41 | fun getCurrentTime(): String {
42 | return SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(Date())
43 | }
44 |
45 | fun convertDateFromMill(mill: Long): String {
46 | return DateFormat.format("dd-MMM-yyyy", mill * 1000).toString()
47 | }
48 |
49 | fun convertTimeFomMill(mill: Long): String {
50 | return DateFormat.format("hh:mm a", mill * 1000).toString()
51 | }
52 |
53 | fun convertDateTimeFomMill(mill: Long): String {
54 | return DateFormat.format("dd-MMM-yyyy hh:mm a", mill * 10).toString()
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/JsonUtils.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | import android.content.res.AssetManager
4 | import android.util.Log
5 | import com.google.gson.Gson
6 | import com.google.gson.JsonArray
7 |
8 | object JsonUtils {
9 | fun AssetManager.readAssetsFile(fileName: String): String =
10 | open(fileName).bufferedReader().use { it.readText() }
11 |
12 | fun generateObjectFromJson(json: String?, type: Class?): T {
13 | Log.d(Constant.TAG(JsonUtils::class.java).toString(), Gson().toString())
14 | return Gson().fromJson(json, type)
15 | }
16 |
17 | fun generateFromJsonArray(json: JsonArray?, type: Class?): T {
18 | Log.d(Constant.TAG(JsonUtils::class.java).toString(), Gson().toString())
19 | return Gson().fromJson(json, type)
20 | }
21 |
22 | fun generateObjectFromJsonArray(json: String?, clazz: Class?>?): List {
23 | Log.d(Constant.TAG(JsonUtils::class.java).toString(), "generateObjectFromJsonArray:Before")
24 | val array: Array = Gson().fromJson(json, clazz)!!
25 | Log.d(Constant.TAG(JsonUtils::class.java).toString(), "generateObjectFromJsonArray: After")
26 | return mutableListOf(*array)
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/LeetDroidGlideModule.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | import android.content.Context
4 | import com.bumptech.glide.GlideBuilder
5 | import com.bumptech.glide.annotation.GlideModule
6 | import com.bumptech.glide.load.engine.DiskCacheStrategy
7 | import com.bumptech.glide.module.AppGlideModule
8 | import com.bumptech.glide.request.RequestOptions
9 |
10 | @GlideModule
11 | class LeetDroidGlideModule : AppGlideModule() {
12 |
13 | override fun applyOptions(context: Context, builder: GlideBuilder) {
14 | super.applyOptions(context, builder)
15 | builder.apply { RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL) }
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/NetworkUtils.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | import android.content.Context
4 | import android.net.ConnectivityManager
5 | import android.net.NetworkCapabilities
6 | import android.net.NetworkInfo
7 | import android.os.Build
8 | import androidx.annotation.RequiresApi
9 |
10 | fun Context.hasNetwork(): Boolean {
11 | val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
12 | return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
13 | checkConnected(connectivityManager)
14 | } else {
15 | checkConnectedLegacy(connectivityManager)
16 | }
17 | }
18 |
19 |
20 | @RequiresApi(Build.VERSION_CODES.M)
21 | fun checkConnected(connectivityManager: ConnectivityManager): Boolean {
22 | val activeNetwork = connectivityManager.activeNetwork
23 | activeNetwork ?: return false
24 | val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
25 | capabilities ?: return false
26 | return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || capabilities.hasTransport(
27 | NetworkCapabilities.TRANSPORT_WIFI
28 | )
29 | }
30 |
31 | fun checkConnectedLegacy(connectivityManager: ConnectivityManager): Boolean {
32 | val networkInfo = connectivityManager.activeNetworkInfo
33 | networkInfo ?: return false
34 | return networkInfo.isConnected && (networkInfo.type == ConnectivityManager.TYPE_WIFI || networkInfo.type == ConnectivityManager.TYPE_MOBILE)
35 | }
36 |
37 | fun checkConnectivity(context: Context): Boolean{
38 | val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
39 | val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
40 |
41 | if(activeNetwork?.isConnected != null){
42 | return activeNetwork.isConnected
43 | } else{
44 | return false
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/SharedPreferences.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | import android.content.Context
4 | import android.content.SharedPreferences
5 |
6 |
7 | class SharedPreferences(context: Context) {
8 |
9 | private val sharedPreferences: SharedPreferences =
10 | context.getSharedPreferences("data", Context.MODE_PRIVATE)
11 |
12 | var questionsFetched: Boolean
13 | get() = sharedPreferences.getBoolean("questionsFetched", false)
14 | set(value) = sharedPreferences.edit().putBoolean("questionsFetched", value).apply()
15 |
16 | var contestsInserted: Boolean
17 | get() = sharedPreferences.getBoolean("contestsInserted", false)
18 | set(value) = sharedPreferences.edit().putBoolean("contestsInserted", value).apply()
19 |
20 | var timerEnded: Boolean
21 | get() = sharedPreferences.getBoolean("timerEnded", false)
22 | set(value) = sharedPreferences.edit().putBoolean("timerEnded", value).apply()
23 |
24 | var userDataLoaded: Boolean
25 | get() = sharedPreferences.getBoolean("userDataLoaded", false)
26 | set(value) = sharedPreferences.edit().putBoolean("userDataLoaded", value).apply()
27 |
28 | var userAdded: Boolean
29 | get() = sharedPreferences.getBoolean("userAdded", false)
30 | set(value) = sharedPreferences.edit().putBoolean("userAdded", value).apply()
31 |
32 | var dailyQuestionLoaded: Boolean
33 | get() = sharedPreferences.getBoolean("dailyQuestionLoaded", false)
34 | set(value) = sharedPreferences.edit().putBoolean("dailyQuestionLoaded", value).apply()
35 |
36 | var dailyQuestionAdded: Boolean
37 | get() = sharedPreferences.getBoolean("dailyQuestionAdded", false)
38 | set(value) = sharedPreferences.edit().putBoolean("dailyQuestionAdded", value).apply()
39 |
40 | var firebaseUserAdded: Boolean
41 | get() = sharedPreferences.getBoolean("firebaseUserAdded", false)
42 | set(value) = sharedPreferences.edit().putBoolean("firebaseUserAdded", value).apply()
43 |
44 | var firebaseUserRegistered: Boolean
45 | get() = sharedPreferences.getBoolean("firebaseUserRegistered", false)
46 | set(value) = sharedPreferences.edit().putBoolean("firebaseUserRegistered", value).apply()
47 |
48 | var dailyNotificationPushed: Boolean
49 | get() = sharedPreferences.getBoolean("minsNotificationPushed", false)
50 | set(value) = sharedPreferences.edit().putBoolean("minsNotificationPushed", value).apply()
51 |
52 | var dayWeeklyNotificationPushed: Boolean
53 | get() = sharedPreferences.getBoolean("dayNotificationPushed", false)
54 | set(value) = sharedPreferences.edit().putBoolean("dayNotificationPushed", value).apply()
55 |
56 | var minsWeeklyNotificationPushed: Boolean
57 | get() = sharedPreferences.getBoolean("minsNotificationPushed", false)
58 | set(value) = sharedPreferences.edit().putBoolean("minsNotificationPushed", value).apply()
59 |
60 | var dayBiWeeklyNotificationPushed: Boolean
61 | get() = sharedPreferences.getBoolean("dayNotificationPushed", false)
62 | set(value) = sharedPreferences.edit().putBoolean("dayNotificationPushed", value).apply()
63 |
64 | var minsBiWeeklyNotificationPushed: Boolean
65 | get() = sharedPreferences.getBoolean("minsNotificationPushed", false)
66 | set(value) = sharedPreferences.edit().putBoolean("minsNotificationPushed", value).apply()
67 |
68 | var statusShown: Boolean
69 | get() = sharedPreferences.getBoolean("minsNotificationPushed", false)
70 | set(value) = sharedPreferences.edit().putBoolean("minsNotificationPushed", value).apply()
71 |
72 | fun removeAllPreferences() {
73 | val editor: SharedPreferences.Editor = sharedPreferences.edit()
74 | editor.clear()
75 | editor.apply()
76 | // sharedPreferences.edit().clear().apply()
77 | }
78 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/StringExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | import android.text.TextUtils
4 |
5 | object StringExtensions {
6 | fun String.isEmailValid(): Boolean {
7 | return !TextUtils.isEmpty(this) && android.util.Patterns.EMAIL_ADDRESS.matcher(this)
8 | .matches()
9 | }
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/closeKeyboard.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils
2 |
3 | import android.app.Activity
4 | import android.view.inputmethod.InputMethodManager
5 |
6 |
7 | fun hideSoftKeyboard(activity: Activity) {
8 | val inputMethodManager: InputMethodManager =
9 | activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
10 | if (inputMethodManager.isActive) {
11 | if (activity.currentFocus != null) {
12 | inputMethodManager.hideSoftInputFromWindow(activity.currentFocus!!.windowToken, 0)
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/dialog/AlertDialogShower.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils.dialog
2 |
3 | import android.app.Activity
4 | import android.app.Dialog
5 | import androidx.appcompat.app.AlertDialog
6 |
7 | class AlertDialogShower constructor(private val activity: Activity) :
8 | DialogShower {
9 | override fun show(dialog: AppDialogs, vararg clickListeners: () -> Unit) {
10 | create(dialog, *clickListeners).show()
11 | }
12 |
13 | override fun create(dialog: AppDialogs, vararg clickListeners: () -> Unit): Dialog {
14 | return AlertDialog.Builder(activity)
15 | .apply {
16 | dialog.title?.let(this::setTitle)
17 | dialog.icon?.let(this::setIcon)
18 | dialog.message?.let { setMessage(activity.getString(it, *bodyArguments(dialog))) }
19 | setPositiveButton(dialog.positiveMessage) { _, _ ->
20 | clickListeners.getOrNull(0)
21 | ?.invoke()
22 | }
23 | dialog.negativeMessage?.let {
24 | setNegativeButton(it) { _, _ ->
25 | clickListeners.getOrNull(1)
26 | ?.invoke()
27 | }
28 | }
29 | dialog.neutralMessage?.let {
30 | setNeutralButton(it) { _, _ ->
31 | clickListeners.getOrNull(2)
32 | ?.invoke()
33 | }
34 | }
35 | dialog.getView?.let { setView(it()) }
36 | setCancelable(dialog.cancelable)
37 | }
38 | .create()
39 | }
40 |
41 | private fun bodyArguments(dialog: AppDialogs) =
42 | if (dialog is AppDialogs.HasBodyFormatArgs) dialog.args.toTypedArray()
43 | else emptyArray()
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/dialog/AppDialogs.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils.dialog
2 |
3 | import android.view.View
4 | import com.cdhiraj40.leetdroid.R
5 |
6 | sealed class AppDialogs(
7 | val title: Int?,
8 | val message: Int?,
9 | val positiveMessage: Int,
10 | val negativeMessage: Int? = null,
11 | val cancelable: Boolean = true,
12 | val icon: Int? = null,
13 | val neutralMessage: Int? = null,
14 | val getView: (() -> View)? = null
15 | ) {
16 | object Logout : AppDialogs(
17 | title = R.string.logout_dialog_title,
18 | message = R.string.logout_dialog_message,
19 | positiveMessage = R.string.yes,
20 | negativeMessage = android.R.string.cancel,
21 | cancelable = true,
22 | icon = R.drawable.ic_baseline_logout_24
23 | )
24 |
25 | object SyncData : AppDialogs(
26 | title = R.string.sync_data,
27 | message = R.string.sync_data_dialog_message,
28 | positiveMessage = R.string.yes,
29 | negativeMessage = android.R.string.cancel,
30 | cancelable = true,
31 | icon = R.drawable.ic_baseline_sync_24
32 | )
33 |
34 | object UsernameWarning : AppDialogs(
35 | title = R.string.warning,
36 | message = R.string.username_warning_message,
37 | positiveMessage = R.string.username_warning_positive_message,
38 | negativeMessage = R.string.username_warning_negative_message,
39 | cancelable = true,
40 | icon = R.drawable.ic_baseline_warning_24
41 | )
42 |
43 | object PremiumList : AppDialogs(
44 | title = R.string.warning,
45 | message = R.string.premium_list_message,
46 | positiveMessage = R.string.premium_list_positive_message,
47 | negativeMessage = android.R.string.cancel,
48 | cancelable = true,
49 | icon = R.drawable.ic_baseline_warning_24
50 | )
51 |
52 | object ReportBug : AppDialogs(
53 | title = R.string.report_bug,
54 | message = R.string.report_bug_message,
55 | positiveMessage = R.string.report_bug_positive_message,
56 | neutralMessage = R.string.report_bug_neutral_message,
57 | cancelable = true,
58 | icon = R.drawable.ic_baseline_bug_report_24
59 | )
60 |
61 |
62 | interface HasBodyFormatArgs {
63 | val args: List
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/dialog/DialogShower.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils.dialog
2 |
3 | import android.app.Dialog
4 |
5 | interface DialogShower {
6 | fun show(
7 | dialog: AppDialogs,
8 | vararg clickListeners: (() -> Unit)
9 | )
10 |
11 | fun create(
12 | dialog: AppDialogs,
13 | vararg clickListeners: (() -> Unit)
14 | ): Dialog
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/extensions/ContextExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils.extensions
2 |
3 | import android.content.ClipData
4 | import android.content.ClipboardManager
5 | import android.content.Context
6 | import android.content.Intent
7 |
8 | import android.widget.Toast
9 |
10 | fun Context?.toast(
11 | stringId: Int,
12 | length: Int = Toast.LENGTH_LONG
13 | ) {
14 | this?.let {
15 | Toast.makeText(this, stringId, length)
16 | .show()
17 | }
18 | }
19 |
20 | fun Context?.toast(
21 | text: String,
22 | length: Int = Toast.LENGTH_LONG
23 | ) {
24 | this?.let {
25 | Toast.makeText(this, text, length)
26 | .show()
27 | }
28 | }
29 |
30 | fun Context.openActivity(it: Class) {
31 | val intent = Intent(this, it)
32 | startActivity(intent)
33 | }
34 |
35 | fun Context.copyToClipboard(text: CharSequence) {
36 | val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
37 | val clip = ClipData.newPlainText("label", text)
38 | clipboard.setPrimaryClip(clip)
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/cdhiraj40/leetdroid/utils/extensions/FragmentExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid.utils.extensions
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.view.View
6 | import android.view.inputmethod.InputMethodManager
7 | import android.widget.RelativeLayout
8 | import androidx.annotation.StringRes
9 | import androidx.core.content.ContextCompat
10 | import androidx.fragment.app.Fragment
11 | import com.cdhiraj40.leetdroid.R
12 | import com.google.android.material.snackbar.Snackbar
13 |
14 |
15 | fun Fragment.closeKeyboard() {
16 | view?.let { activity?.hideKeyboard(it) }
17 | }
18 |
19 | fun Context.hideKeyboard(view: View) {
20 | val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
21 | inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
22 | }
23 |
24 | fun showSnackBar(activity: Activity, message: String?) {
25 | val rootView = activity.window.decorView.findViewById(android.R.id.content)
26 | val snackbar = Snackbar.make(rootView, message!!, Snackbar.LENGTH_SHORT)
27 | snackbar.anchorView = activity.findViewById(R.id.bottom_navigation)
28 | snackbar.show()
29 | }
30 |
31 |
32 | fun showSnackBarWithAction(
33 | activity: Activity,
34 | message: String?,
35 | actionRes: String,
36 | color: Int? = null,
37 | listener: (View) -> Unit
38 | ) {
39 | val rootView = activity.window.decorView.findViewById(android.R.id.content)
40 | val snackbar = Snackbar.make(rootView, message!!, Snackbar.LENGTH_SHORT)
41 | snackbar.setAction(actionRes, listener)
42 | snackbar.anchorView = activity.findViewById(R.id.bottom_navigation)
43 | snackbar.show()
44 | }
45 |
46 | fun Snackbar.action(@StringRes actionRes: Int, color: Int? = null, listener: (View) -> Unit) {
47 | action(view.resources.getString(actionRes), color, listener)
48 | }
49 |
50 | fun Snackbar.action(action: String, color: Int? = null, listener: (View) -> Unit) {
51 | setAction(action, listener)
52 | color?.let { setActionTextColor(ContextCompat.getColor(context, color)) }
53 | }
54 |
55 | // usage: view1.below(view2)
56 | infix fun View.below(view: View) {
57 | (this.layoutParams as? RelativeLayout.LayoutParams)?.addRule(RelativeLayout.BELOW, view.id)
58 | }
59 |
60 | // usage: view1.above(view2)
61 | infix fun View.above(view: View) {
62 | (this.layoutParams as? RelativeLayout.LayoutParams)?.addRule(RelativeLayout.ABOVE, view.id)
63 | }
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/app_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/drawable/app_banner.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/drawable/app_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/app_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/drawable/app_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_blue_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_blue_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_blue_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/circle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
8 |
9 |
10 |
11 |
12 | -
13 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/contest_selected_dot_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/contest_selected_dot_orange.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/contest_selected_dot_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/contest_unselected_dot_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/contest_unselected_dot_orange.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/contest_unselected_dot_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/contest_viewpager_selector_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/dark_glass_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
11 |
12 |
13 |
14 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_all_inbox_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_arrow_back_24.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_arrow_drop_down_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_beenhere_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_bug_report_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_code_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_computer_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_content_copy_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_discuss_24.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_earbuds_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_edit_calendar_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_filter_list_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_folder_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_gesture_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_home_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_info_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_link_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_location_on_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_logout_24.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_menu_book_20.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_new_releases_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_open_in_new_24.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_search_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_share_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_shuffle_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_star_rate_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_sync_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_topic_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_view_list_24.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_views_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_baseline_warning_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_contribute.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_question_solution.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_round_person_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/layout_border.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/light_glass_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
11 |
12 |
13 |
14 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/drawable/like.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/login_layout_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/question_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/drawable/question_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/question_solution.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/drawable/question_solution.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/round_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
27 |
28 |
40 |
41 |
42 |
43 |
44 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/all_questions_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
32 |
33 |
45 |
46 |
55 |
56 |
67 |
68 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/contibutors_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
27 |
28 |
42 |
43 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/drawer_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_contributors.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
15 |
20 |
21 |
25 |
26 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_discussion_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
26 |
27 |
35 |
36 |
37 |
38 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_general_discussion_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
26 |
27 |
36 |
37 |
38 |
39 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_license.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_question_discussion.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
18 |
19 |
25 |
26 |
30 |
31 |
32 |
33 |
34 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_question_solution.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
23 |
27 |
28 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_recent_submission.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
23 |
24 |
28 |
29 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
44 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_trending_discussion.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
18 |
19 |
23 |
24 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/general_error_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
23 |
24 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_no_questions_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
24 |
25 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_no_solution.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
23 |
24 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_paid_question.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
23 |
24 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/license_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
32 |
33 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/loading_screen_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
21 |
22 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recent_submissions_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
36 |
37 |
50 |
51 |
52 |
66 |
67 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/all_questions_list_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/general_discussion_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main_activity_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/my_profile_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/navigation_drawer_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/navigation_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/navigation_question.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values-night/strings_others.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 | #265AE8
11 | #ffb347
12 | #6FB6F4
13 | #3E97F0
14 | #757575
15 | #FFFF99
16 |
17 |
18 | #E6EFFF
19 | #007FFF
20 | #002D62
21 |
22 |
23 | #4cbb17
24 | #ffd800
25 | #FF3131
26 |
27 | #dfff00
28 |
29 |
30 | #FFD700
31 | #FFD700
32 |
33 | #D3D3D3
34 |
35 | #4cbb17
36 | #ce2029
37 |
38 | #FFA384
39 | #FFA384
40 |
41 | #5855AF
42 | #B4FEE7
43 | #B8EE30
44 | #5885AF
45 | #58A5AF
46 | #2BB8B3
47 | #72c6ff
48 | #b5e3af
49 | #b28bff
50 | #b2b2ff
51 | #53DBFB
52 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string_all_questions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Acceptance Rate: %1$s
4 | No questions found with this search.
5 | All Topics
6 |
7 | Algorithms
8 | Database
9 | Shell
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string_authentication.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Welcome Back! \n Sign in to continue!
4 | Welcome to LeetDroid! \n Sign up to continue!
5 | Welcome to LeetDroid! \n Sign up to continue!
6 |
7 | Password
8 | Email
9 | LeetCode Username
10 | Forgot Password?
11 |
12 | Send Email
13 | Email has been sent
14 | Open Gmail
15 | Didn\'t get any email? Do Check your spam folder or try again with a registered email.
16 | Email will be only sent to registered users
17 | Forgot Password? \n No worries
18 | We’ve sent you an email with instructions to reset your password*
19 |
20 | Open Gmail?
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string_dialogs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | YES
5 | Warning
6 |
7 |
8 | Logout
9 | Do you want to logout?
10 |
11 |
12 | Sync Data
13 | Do you want to sync the data? \nThis may take around 10–20 seconds depending on your internet speed.
14 |
15 |
16 | You will not be able to change you username later!
17 | Proceed
18 | Change
19 |
20 |
21 | This list is premium and contains all premium questions that can\'t be opened.\nYou will still be able to see title of questions. Do you want to open?
22 | Take me there
23 | Which platform would you like to use to share bug description?
24 | Github
25 | Email
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PROBLEM SET
4 | RANDOM\nQUESTION
5 | Get upcoming contest details, notifications a day and 30 mins before contests
6 | Add reminder to your Google Calendar
7 | See all the questions (around 1000+) along with their solutions, discussion for every question.
8 | We all get bored after searching for a perfect question, click here and get a random question to practice on.
9 | "Get daily new questions to solve, that are same from leetcode's daily challenges. "
10 | "Checkout the trending Discussions happening on LeetCode. You can click on the button to see in whole screen."
11 | Daily Challenge
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string_problems.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | FEATURED LISTS
5 | PROBLEM\nTOPICS
6 | PROBLEM\nDIFFICULTY
7 | PROBLEM TAGS
8 | ARRAY
9 | STRING
10 | HASH TABLE
11 | DYNAMIC PROGRAMMING
12 | SORTING
13 | GREEDY
14 | BACKTRACKING
15 | BIT\nMANIPULATION
16 | SLIDING WINDOW
17 | RECURSION
18 |
19 |
20 | EASY
21 | MEDIUM
22 | HARD
23 |
24 |
25 | TOP INTERVIEW QUESTIONS
26 | TOP 100 LIKED QUESTIONS
27 | LEETCODE CURATED ALGO 170
28 | LEETCODE CURATED SQL 70
29 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string_programming_languages.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Java
4 | Python
5 | python3
6 | MySQL
7 | MS SQL Server
8 | Elixir
9 | Erlang
10 | Racket
11 | TypeScript
12 | PHP
13 | Rust
14 | html
15 | Scala
16 | Go
17 | Swift
18 | Bash
19 | Ruby
20 | JavaScript
21 | Oracle
22 | Kotlin
23 | Python ML
24 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string_question_solution.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | No solution found for this question.
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string_recent_submissions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Most Recent Submissions
4 | Recent Submissions
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | LeetDroid
3 |
4 | Hello blank fragment
5 | Home
6 | Discussions
7 | Profile
8 | All Question List
9 | Question Description
10 | Solution
11 | Share Link?
12 | SignUpActivity
13 |
14 | First Fragment
15 | Second Fragment
16 | Next
17 | Previous
18 |
19 | Hello first fragment
20 | Hello second fragment. Arg: %1$s
21 | REGISTER
22 | LOGIN
23 | sync
24 |
25 | Log Out
26 |
27 | PAID
28 | search
29 | Explore Problems
30 |
31 | Something went wrong, \nplease try again later or Restart the App.
32 | Testcases
33 | location
34 | Education
35 | Rate Us
36 | Report bug
37 | Suggest new feature
38 | Source Code
39 | Contribute
40 | About
41 | Others
42 |
43 | Messages
44 | Sync
45 |
46 |
47 | Your signature
48 | Default reply action
49 |
50 |
51 | Sync email periodically
52 | Download incoming attachments
53 | Automatically download attachments for incoming emails
54 |
55 | Only download attachments when manually requested
56 | LeetDroid version
57 | Contributors
58 | Any contributions you make are greatly appreciated. Here are the contributors of the app.
59 | Licenses
60 | Here are the epic libraries used by the LeetDroid.
61 | Internet is off. Please check your internet connection and try again.
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings_general_discussions.xml:
--------------------------------------------------------------------------------
1 |
2 | Categories
3 | Interview Questions
4 | Interview Experience
5 | Compensation
6 | Career
7 | Study Guide
8 | General Discussion
9 |
10 | Concurrency
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings_myprofile.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | user profile
5 | username
6 | Full Name
7 | CSE TCET\'24 | ANDROID DEVELOPER | NIRMAAN HYPERLOOP |3⭐ @codechef
8 | Website
9 | Points
10 | Problems Solved
11 | Easy
12 | Medium
13 | Hard
14 |
15 | %1$s %2$s
16 | Contest Details
17 | Ranking:
18 | No of Contest Attended:
19 | Rating:
20 | Global Ranking:
21 | Rating after contest:
22 | Contest ranking:
23 | Recent Contests
24 | Did not attend the Contest!
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings_question.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | %1$s
4 | Sorry we can\'t open a paid question.
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/preferences_about.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/cdhiraj40/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.cdhiraj40.leetdroid
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/example/cdhiraj40/TimeZoneUTCRule.kt:
--------------------------------------------------------------------------------
1 | package com.example.cdhiraj40
2 |
3 | import org.junit.rules.TestWatcher
4 | import org.junit.runner.Description
5 | import java.util.*
6 |
7 | class UTCRule : TestWatcher() {
8 | private val origDefault: TimeZone = TimeZone.getDefault()
9 | override fun starting(description: Description) {
10 | TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
11 | }
12 |
13 | override fun finished(description: Description) {
14 | TimeZone.setDefault(origDefault)
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/example/cdhiraj40/utils/DateUtilsTest.kt:
--------------------------------------------------------------------------------
1 | package com.example.cdhiraj40.utils
2 |
3 | import com.cdhiraj40.leetdroid.utils.DateUtils.formatISO8601Date
4 | import com.cdhiraj40.leetdroid.utils.DateUtils.getDate
5 | import com.cdhiraj40.leetdroid.utils.DateUtils.getHours
6 | import com.cdhiraj40.leetdroid.utils.DateUtils.getSeconds
7 | import com.cdhiraj40.leetdroid.utils.DateUtils.getTime
8 | import com.example.cdhiraj40.UTCRule
9 | import com.google.common.truth.Truth.assertThat
10 | import org.junit.Rule
11 | import org.junit.Test
12 | import org.junit.runner.RunWith
13 | import org.junit.runners.JUnit4
14 | import java.time.Instant
15 | import java.time.OffsetDateTime
16 | import java.time.format.DateTimeFormatter
17 | import java.util.*
18 |
19 |
20 | @RunWith(JUnit4::class)
21 | class DateUtilsTest {
22 |
23 | private val dateISO8601 = "2022-02-19T14:30:00.000Z"
24 |
25 | @get:Rule
26 | var utcRule: UTCRule = UTCRule()
27 |
28 | @Test
29 | fun parseISO8601DateTest() {
30 | val result = parseISO8601Date(dateISO8601).toString()
31 | val expected = "Sat Feb 19 14:30:00 UTC 2022"
32 | assertThat(result).isEqualTo(expected)
33 | }
34 |
35 | @Test
36 | fun formatISO8601DateTest() {
37 | val instant = parseISO8601Date(dateISO8601)
38 | val result = formatISO8601Date(instant)
39 | val expected = "Sat Feb 19 14:30:00 UTC 2022"
40 | assertThat(result.toString()).isEqualTo(expected)
41 | }
42 |
43 | @Test
44 | fun getDateTest() {
45 | val result = getDate(parseISO8601Date(dateISO8601))
46 | val expected = "Feb 19, 2022"
47 | assertThat(result).isEqualTo(expected)
48 | }
49 |
50 | @Test
51 | fun getTimeTest() {
52 | val result = getTime(parseISO8601Date(dateISO8601))
53 | val expected = "14:30"
54 | assertThat(result).isEqualTo(expected)
55 | }
56 |
57 | @Test
58 | fun getHoursTest() {
59 | val result = getHours("5400")
60 | val expected = "1.5"
61 | assertThat(result).isEqualTo(expected)
62 | }
63 |
64 | @Test
65 | fun getSecondsTest() {
66 | val result = getSeconds("00:01")
67 | val expected = "60"
68 | assertThat(result.toString()).isEqualTo(expected)
69 | }
70 |
71 | private fun parseISO8601Date(date: String): Date {
72 | val timeFormatter = DateTimeFormatter.ISO_DATE_TIME
73 | val offsetDateTime = OffsetDateTime.parse(date, timeFormatter)
74 |
75 | return Date.from(Instant.from(offsetDateTime))
76 | }
77 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | mavenCentral()
6 | maven { url 'https://jitpack.io' }
7 | }
8 | dependencies {
9 | classpath "com.android.tools.build:gradle:7.0.3"
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
11 | classpath 'com.google.gms:google-services:4.3.10'
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | allprojects {
17 | repositories {
18 | }
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdhiraj40/LeetDroid/a4a42158297c9cb48600259febd7b1d4916a4bb6/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jan 14 12:51:38 IST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
3 | repositories {
4 | google()
5 | mavenCentral()
6 | maven { url 'https://jitpack.io' }
7 | }
8 | }
9 | rootProject.name = "LeetDroid"
10 | include ':app'
11 |
--------------------------------------------------------------------------------