├── .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 | 4 | 5 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/menu/general_discussion_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main_activity_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/menu/my_profile_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/menu/navigation_drawer_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 18 | 19 | 23 | 24 | 25 | 26 | 30 | 31 | 35 | 36 | 40 | 41 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/menu/navigation_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 12 | 16 | 17 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/menu/navigation_question.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 16 | -------------------------------------------------------------------------------- /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 | 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 | 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 | --------------------------------------------------------------------------------