├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── chore.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── auto_label.yml ├── dependabot.yml ├── issue_label_bot.yaml └── release-drafter.yml ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── schemas │ └── org.fossasia.openevent.general.OpenEventDatabase │ │ ├── 4.json │ │ ├── 5.json │ │ ├── 6.json │ │ ├── 7.json │ │ ├── 8.json │ │ └── 9.json └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── fossasia │ │ └── openevent │ │ └── general │ │ └── ExampleInstrumentedTest.java │ ├── fdroid │ └── java │ │ └── org │ │ └── fossasia │ │ └── openevent │ │ └── general │ │ ├── auth │ │ ├── SmartAuthUtil.kt │ │ └── SmartAuthViewModel.kt │ │ ├── di │ │ └── FlavorSpecificModules.kt │ │ └── search │ │ └── location │ │ ├── GeoLocationViewModel.kt │ │ └── LocationServiceImpl.kt │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ │ └── org │ │ │ └── fossasia │ │ │ └── openevent │ │ │ └── general │ │ │ ├── CircleTransform.kt │ │ │ ├── MainActivity.kt │ │ │ ├── OpenEventDatabase.kt │ │ │ ├── OpenEventGeneral.kt │ │ │ ├── RotateBitmap.kt │ │ │ ├── StartupViewModel.kt │ │ │ ├── about │ │ │ ├── AboutEventFragment.kt │ │ │ └── AboutEventViewModel.kt │ │ │ ├── attendees │ │ │ ├── Attendee.kt │ │ │ ├── AttendeeApi.kt │ │ │ ├── AttendeeConverter.kt │ │ │ ├── AttendeeDao.kt │ │ │ ├── AttendeeFragment.kt │ │ │ ├── AttendeeRecyclerAdapter.kt │ │ │ ├── AttendeeService.kt │ │ │ ├── AttendeeViewHolder.kt │ │ │ ├── AttendeeViewModel.kt │ │ │ ├── ListAttendeeConverter.kt │ │ │ └── forms │ │ │ │ ├── CustomForm.kt │ │ │ │ └── FormIdentifier.kt │ │ │ ├── auth │ │ │ ├── AuthApi.kt │ │ │ ├── AuthFragment.kt │ │ │ ├── AuthHolder.kt │ │ │ ├── AuthService.kt │ │ │ ├── AuthViewModel.kt │ │ │ ├── CheckEmailResponse.kt │ │ │ ├── CropImageFragment.kt │ │ │ ├── EditProfileFragment.kt │ │ │ ├── EditProfileViewModel.kt │ │ │ ├── EmailVerificationResponse.kt │ │ │ ├── ImageResponse.kt │ │ │ ├── Login.kt │ │ │ ├── LoginFragment.kt │ │ │ ├── LoginResponse.kt │ │ │ ├── LoginViewModel.kt │ │ │ ├── ProfileFragment.kt │ │ │ ├── ProfileViewModel.kt │ │ │ ├── RequestAuthenticator.kt │ │ │ ├── RequestEmailVerification.kt │ │ │ ├── RequestPasswordReset.kt │ │ │ ├── ResetPasswordResponse.kt │ │ │ ├── SignUp.kt │ │ │ ├── SignUpFragment.kt │ │ │ ├── SignUpViewModel.kt │ │ │ ├── Token.kt │ │ │ ├── UploadImage.kt │ │ │ ├── User.kt │ │ │ ├── UserDao.kt │ │ │ ├── UserId.kt │ │ │ ├── UserIdConverter.kt │ │ │ ├── change │ │ │ │ ├── ChangeRequestToken.kt │ │ │ │ ├── ChangeRequestTokenResponse.kt │ │ │ │ └── Password.kt │ │ │ └── forgot │ │ │ │ ├── Email.kt │ │ │ │ ├── PasswordReset.kt │ │ │ │ ├── RequestToken.kt │ │ │ │ └── RequestTokenResponse.kt │ │ │ ├── common │ │ │ ├── EventsDiffCallback.kt │ │ │ ├── RecyclerViewCallbacks.kt │ │ │ └── SingleLiveEvent.kt │ │ │ ├── connectivity │ │ │ └── MutableConnectionLiveData.kt │ │ │ ├── data │ │ │ ├── Network.kt │ │ │ ├── Preference.kt │ │ │ └── Resource.kt │ │ │ ├── di │ │ │ ├── HostSelectionInterceptor.kt │ │ │ └── Modules.kt │ │ │ ├── discount │ │ │ ├── DiscountApi.kt │ │ │ └── DiscountCode.kt │ │ │ ├── event │ │ │ ├── Event.kt │ │ │ ├── EventApi.kt │ │ │ ├── EventDao.kt │ │ │ ├── EventDetailsFragment.kt │ │ │ ├── EventDetailsViewModel.kt │ │ │ ├── EventId.kt │ │ │ ├── EventIdConverter.kt │ │ │ ├── EventService.kt │ │ │ ├── EventUtils.kt │ │ │ ├── EventViewHolder.kt │ │ │ ├── EventsFragment.kt │ │ │ ├── EventsListAdapter.kt │ │ │ ├── EventsViewModel.kt │ │ │ ├── codeofconduct │ │ │ │ └── ConductCodeFragment.kt │ │ │ ├── faq │ │ │ │ ├── EventFAQ.kt │ │ │ │ ├── EventFAQApi.kt │ │ │ │ ├── EventFAQFragment.kt │ │ │ │ ├── EventFAQViewModel.kt │ │ │ │ ├── FAQRecyclerAdapter.kt │ │ │ │ └── FAQViewHolder.kt │ │ │ ├── location │ │ │ │ ├── EventLocation.kt │ │ │ │ └── EventLocationApi.kt │ │ │ ├── paging │ │ │ │ ├── EventsDataSource.kt │ │ │ │ ├── EventsDataSourceFactory.kt │ │ │ │ ├── SimilarEventsDataSource.kt │ │ │ │ └── SimilarEventsDataSourceFactory.kt │ │ │ ├── similarevent │ │ │ │ ├── SimilarEventViewHolder.kt │ │ │ │ └── SimilarEventsListAdapter.kt │ │ │ ├── subtopic │ │ │ │ ├── EventSubTopic.kt │ │ │ │ └── EventSubTopicConverter.kt │ │ │ ├── tax │ │ │ │ ├── Tax.kt │ │ │ │ ├── TaxApi.kt │ │ │ │ ├── TaxDao.kt │ │ │ │ └── TaxService.kt │ │ │ ├── topic │ │ │ │ ├── EventTopic.kt │ │ │ │ ├── EventTopicApi.kt │ │ │ │ ├── EventTopicConverter.kt │ │ │ │ └── EventTopicsDao.kt │ │ │ └── types │ │ │ │ ├── EventType.kt │ │ │ │ ├── EventTypeConverter.kt │ │ │ │ └── EventTypesApi.kt │ │ │ ├── favorite │ │ │ ├── FavoriteEvent.kt │ │ │ ├── FavoriteEventApi.kt │ │ │ ├── FavoriteEventViewHolder.kt │ │ │ ├── FavoriteEventsListAdapter.kt │ │ │ ├── FavoriteEventsViewModel.kt │ │ │ └── FavoriteFragment.kt │ │ │ ├── feedback │ │ │ ├── Feedback.kt │ │ │ ├── FeedbackApi.kt │ │ │ ├── FeedbackDao.kt │ │ │ ├── FeedbackFragment.kt │ │ │ ├── FeedbackRecyclerAdapter.kt │ │ │ ├── FeedbackService.kt │ │ │ ├── FeedbackViewHolder.kt │ │ │ └── FeedbackViewModel.kt │ │ │ ├── location │ │ │ └── LocationExceptions.kt │ │ │ ├── notification │ │ │ ├── Notification.kt │ │ │ ├── NotificationApi.kt │ │ │ ├── NotificationDao.kt │ │ │ ├── NotificationFragment.kt │ │ │ ├── NotificationService.kt │ │ │ ├── NotificationViewModel.kt │ │ │ ├── NotificationsRecyclerAdapter.kt │ │ │ └── NotificationsViewHolder.kt │ │ │ ├── order │ │ │ ├── Charge.kt │ │ │ ├── ConfirmOrder.kt │ │ │ ├── ExpiredOrderFragment.kt │ │ │ ├── Order.kt │ │ │ ├── OrderApi.kt │ │ │ ├── OrderCompletedFragment.kt │ │ │ ├── OrderCompletedViewModel.kt │ │ │ ├── OrderDao.kt │ │ │ ├── OrderDataSource.kt │ │ │ ├── OrderDataSourceFactory.kt │ │ │ ├── OrderDetailsFragment.kt │ │ │ ├── OrderDetailsRecyclerAdapter.kt │ │ │ ├── OrderDetailsViewHolder.kt │ │ │ ├── OrderDetailsViewModel.kt │ │ │ ├── OrderService.kt │ │ │ ├── OrdersPagedListAdapter.kt │ │ │ ├── OrdersUnderUserFragment.kt │ │ │ ├── OrdersUnderUserViewModel.kt │ │ │ ├── OrdersViewHolder.kt │ │ │ ├── QrCode.kt │ │ │ └── invoice │ │ │ │ └── DownloadInvoiceService.kt │ │ │ ├── paypal │ │ │ ├── Paypal.kt │ │ │ ├── PaypalApi.kt │ │ │ └── PaypalPaymentResponse.kt │ │ │ ├── search │ │ │ ├── SearchEventsDataSource.kt │ │ │ ├── SearchEventsDataSourceFactory.kt │ │ │ ├── SearchFilterFragment.kt │ │ │ ├── SearchFragment.kt │ │ │ ├── SearchPagedListAdapter.kt │ │ │ ├── SearchResultsFragment.kt │ │ │ ├── SearchResultsViewModel.kt │ │ │ ├── SearchViewModel.kt │ │ │ ├── location │ │ │ │ ├── LocationAdapter.kt │ │ │ │ ├── LocationService.kt │ │ │ │ ├── LocationViewHolder.kt │ │ │ │ ├── PlaceSuggestionViewHolder.kt │ │ │ │ ├── PlaceSuggestionsAdapter.kt │ │ │ │ ├── SearchLocationFragment.kt │ │ │ │ └── SearchLocationViewModel.kt │ │ │ ├── recentsearch │ │ │ │ ├── RecentSearchAdapter.kt │ │ │ │ └── RecentSearchViewHolder.kt │ │ │ ├── time │ │ │ │ ├── SearchTimeFragment.kt │ │ │ │ └── SearchTimeViewModel.kt │ │ │ └── type │ │ │ │ ├── SearchTypeAdapter.kt │ │ │ │ ├── SearchTypeFragment.kt │ │ │ │ └── SearchTypeViewModel.kt │ │ │ ├── sessions │ │ │ ├── Session.kt │ │ │ ├── SessionApi.kt │ │ │ ├── SessionDao.kt │ │ │ ├── SessionFragment.kt │ │ │ ├── SessionRecyclerAdapter.kt │ │ │ ├── SessionService.kt │ │ │ ├── SessionViewHolder.kt │ │ │ ├── SessionViewModel.kt │ │ │ ├── microlocation │ │ │ │ ├── MicroLocation.kt │ │ │ │ └── MicroLocationConverter.kt │ │ │ ├── sessiontype │ │ │ │ ├── SessionType.kt │ │ │ │ └── SessionTypeConverter.kt │ │ │ └── track │ │ │ │ ├── Track.kt │ │ │ │ └── TrackConverter.kt │ │ │ ├── settings │ │ │ ├── Settings.kt │ │ │ ├── SettingsApi.kt │ │ │ ├── SettingsDao.kt │ │ │ ├── SettingsFragment.kt │ │ │ ├── SettingsService.kt │ │ │ └── SettingsViewModel.kt │ │ │ ├── social │ │ │ ├── SocialLink.kt │ │ │ ├── SocialLinkApi.kt │ │ │ ├── SocialLinksDao.kt │ │ │ ├── SocialLinksRecyclerAdapter.kt │ │ │ ├── SocialLinksService.kt │ │ │ └── SocialLinksViewHolder.kt │ │ │ ├── speakercall │ │ │ ├── EditSpeakerFragment.kt │ │ │ ├── EditSpeakerViewModel.kt │ │ │ ├── Proposal.kt │ │ │ ├── SpeakersCall.kt │ │ │ ├── SpeakersCallConverter.kt │ │ │ ├── SpeakersCallDao.kt │ │ │ ├── SpeakersCallFragment.kt │ │ │ ├── SpeakersCallProposalFragment.kt │ │ │ ├── SpeakersCallProposalViewModel.kt │ │ │ ├── SpeakersCallViewModel.kt │ │ │ └── form │ │ │ │ ├── SessionIdentifier.kt │ │ │ │ └── SpeakerIdentifier.kt │ │ │ ├── speakers │ │ │ ├── ListSpeakerIdConverter.kt │ │ │ ├── Speaker.kt │ │ │ ├── SpeakerApi.kt │ │ │ ├── SpeakerDao.kt │ │ │ ├── SpeakerFragment.kt │ │ │ ├── SpeakerId.kt │ │ │ ├── SpeakerRecyclerAdapter.kt │ │ │ ├── SpeakerService.kt │ │ │ ├── SpeakerViewHolder.kt │ │ │ ├── SpeakerViewModel.kt │ │ │ ├── SpeakerWithEvent.kt │ │ │ └── SpeakerWithEventDao.kt │ │ │ ├── sponsor │ │ │ ├── Sponsor.kt │ │ │ ├── SponsorApi.kt │ │ │ ├── SponsorDao.kt │ │ │ ├── SponsorRecyclerAdapter.kt │ │ │ ├── SponsorService.kt │ │ │ ├── SponsorUtil.kt │ │ │ ├── SponsorViewHolder.kt │ │ │ ├── SponsorWIthEvent.kt │ │ │ ├── SponsorWithEventDao.kt │ │ │ ├── SponsorsDetailAdapter.kt │ │ │ ├── SponsorsFragment.kt │ │ │ └── SponsorsViewModel.kt │ │ │ ├── ticket │ │ │ ├── Ticket.kt │ │ │ ├── TicketApi.kt │ │ │ ├── TicketDao.kt │ │ │ ├── TicketDetailsRecyclerAdapter.kt │ │ │ ├── TicketDetailsViewHolder.kt │ │ │ ├── TicketId.kt │ │ │ ├── TicketIdAndQtyWrapper.kt │ │ │ ├── TicketIdConverter.kt │ │ │ ├── TicketPriceRange.kt │ │ │ ├── TicketService.kt │ │ │ ├── TicketViewHolder.kt │ │ │ ├── TicketsFragment.kt │ │ │ ├── TicketsRecyclerAdapter.kt │ │ │ └── TicketsViewModel.kt │ │ │ ├── utils │ │ │ ├── AppLinkData.kt │ │ │ ├── AppLinkUtils.kt │ │ │ ├── DataBindingAdapters.kt │ │ │ ├── DateTimeUtils.kt │ │ │ ├── Error.kt │ │ │ ├── ErrorUtils.kt │ │ │ ├── HttpErrors.kt │ │ │ ├── ImageUtils.kt │ │ │ ├── JWTUtils.java │ │ │ ├── StringUtils.kt │ │ │ ├── Utils.kt │ │ │ └── extensions │ │ │ │ ├── FragmentExt.kt │ │ │ │ ├── LiveDataExtensions.kt │ │ │ │ ├── RxExtensions.kt │ │ │ │ └── ViewExt.kt │ │ │ └── welcome │ │ │ └── WelcomeFragment.kt │ └── res │ │ ├── anim │ │ ├── fade_in.xml │ │ ├── fade_out.xml │ │ ├── slide_down.xml │ │ ├── slide_in_left.xml │ │ ├── slide_in_right.xml │ │ ├── slide_out_left.xml │ │ ├── slide_out_right.xml │ │ └── slide_up.xml │ │ ├── color │ │ ├── navigation_item.xml │ │ └── text_color_chip_state_list.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── background_fragment.xml │ │ ├── background_fragment_search.xml │ │ ├── background_splash.xml │ │ ├── border.xml │ │ ├── border_background_ticket_timer.xml │ │ ├── border_curved.xml │ │ ├── border_order_status.xml │ │ ├── circle_shape.xml │ │ ├── curved_border.xml │ │ ├── filled_border.xml │ │ ├── foreground_black_blur.xml │ │ ├── header.png │ │ ├── ic_account_circle_grey.xml │ │ ├── ic_arrow_back_black.xml │ │ ├── ic_arrow_back_white_cct.png │ │ ├── ic_bank.xml │ │ ├── ic_baseline_arrow_forward.xml │ │ ├── ic_baseline_calendar.xml │ │ ├── ic_baseline_event.xml │ │ ├── ic_baseline_event_grey.xml │ │ ├── ic_baseline_favorite.xml │ │ ├── ic_baseline_favorite_border.xml │ │ ├── ic_baseline_favorite_border_white.xml │ │ ├── ic_baseline_favorite_white.xml │ │ ├── ic_baseline_refund.xml │ │ ├── ic_baseline_tick.xml │ │ ├── ic_baseline_ticket.xml │ │ ├── ic_bio.xml │ │ ├── ic_blogger.xml │ │ ├── ic_camera.xml │ │ ├── ic_cash.xml │ │ ├── ic_check_black.xml │ │ ├── ic_checked.xml │ │ ├── ic_cheque.xml │ │ ├── ic_circle.xml │ │ ├── ic_clear.xml │ │ ├── ic_credit_card.xml │ │ ├── ic_crop.xml │ │ ├── ic_edit.xml │ │ ├── ic_email.xml │ │ ├── ic_email_black.xml │ │ ├── ic_event.xml │ │ ├── ic_exit_to_app_black.xml │ │ ├── ic_expand_icon.xml │ │ ├── ic_facebook.xml │ │ ├── ic_faq.xml │ │ ├── ic_filter.xml │ │ ├── ic_flickr.xml │ │ ├── ic_github.xml │ │ ├── ic_google_plus.xml │ │ ├── ic_image.xml │ │ ├── ic_language_black.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_link_black.xml │ │ ├── ic_linkedin.xml │ │ ├── ic_location_on_black.xml │ │ ├── ic_location_pin.xml │ │ ├── ic_location_world.xml │ │ ├── ic_lock_black.xml │ │ ├── ic_mail_outline_black.xml │ │ ├── ic_map_black.xml │ │ ├── ic_no_internet.xml │ │ ├── ic_notifications_none.xml │ │ ├── ic_notifications_white.xml │ │ ├── ic_open_event.png │ │ ├── ic_organization.xml │ │ ├── ic_outline_account_circle.xml │ │ ├── ic_outline_ticket.xml │ │ ├── ic_paypal.xml │ │ ├── ic_person.xml │ │ ├── ic_person_add.xml │ │ ├── ic_person_black.xml │ │ ├── ic_position.xml │ │ ├── ic_search_grey.xml │ │ ├── ic_search_white.xml │ │ ├── ic_settings.xml │ │ ├── ic_share_grey.xml │ │ ├── ic_share_white.xml │ │ ├── ic_speakers_call.xml │ │ ├── ic_speakers_call_closed.xml │ │ ├── ic_speakers_call_open.xml │ │ ├── ic_star_border.xml │ │ ├── ic_tick_inside_circle.xml │ │ ├── ic_time.xml │ │ ├── ic_track.xml │ │ ├── ic_trash.xml │ │ ├── ic_twitter.xml │ │ ├── ic_website.xml │ │ ├── ic_wikipedia.xml │ │ ├── ic_youtube.xml │ │ ├── round_background.xml │ │ ├── round_image.xml │ │ ├── round_shape.xml │ │ ├── scrim_shape.xml │ │ └── splash_logo.png │ │ ├── layout-land │ │ ├── fragment_search.xml │ │ ├── fragment_welcome.xml │ │ └── item_card_order_details.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── content_event.xml │ │ ├── content_fetching_event_error.xml │ │ ├── content_no_internet.xml │ │ ├── dialog_api_configuration.xml │ │ ├── dialog_change_password.xml │ │ ├── dialog_confirm_delete_account.xml │ │ ├── dialog_delete_account.xml │ │ ├── dialog_edit_profile_image.xml │ │ ├── dialog_feedback.xml │ │ ├── dialog_filter_order.xml │ │ ├── dialog_login_to_like.xml │ │ ├── dialog_rate_us.xml │ │ ├── dialog_reset_password.xml │ │ ├── event_type_list.xml │ │ ├── fragment_about_event.xml │ │ ├── fragment_attendee.xml │ │ ├── fragment_auth.xml │ │ ├── fragment_conduct_code.xml │ │ ├── fragment_crop_image.xml │ │ ├── fragment_edit_profile.xml │ │ ├── fragment_event.xml │ │ ├── fragment_event_faq.xml │ │ ├── fragment_events.xml │ │ ├── fragment_expired_order.xml │ │ ├── fragment_favorite.xml │ │ ├── fragment_feedback.xml │ │ ├── fragment_login.xml │ │ ├── fragment_notification.xml │ │ ├── fragment_order_completed.xml │ │ ├── fragment_order_details.xml │ │ ├── fragment_orders_under_user.xml │ │ ├── fragment_profile.xml │ │ ├── fragment_proposal_speaker.xml │ │ ├── fragment_search.xml │ │ ├── fragment_search_filter.xml │ │ ├── fragment_search_location.xml │ │ ├── fragment_search_results.xml │ │ ├── fragment_search_time.xml │ │ ├── fragment_search_type.xml │ │ ├── fragment_session.xml │ │ ├── fragment_signup.xml │ │ ├── fragment_speaker.xml │ │ ├── fragment_speakers_call.xml │ │ ├── fragment_speakers_call_proposal.xml │ │ ├── fragment_sponsors.xml │ │ ├── fragment_tickets.xml │ │ ├── fragment_welcome.xml │ │ ├── item_attendee.xml │ │ ├── item_card_events.xml │ │ ├── item_card_favorite_event.xml │ │ ├── item_card_notification.xml │ │ ├── item_card_order.xml │ │ ├── item_card_order_details.xml │ │ ├── item_card_similar_events.xml │ │ ├── item_enlarged_qr.xml │ │ ├── item_faq.xml │ │ ├── item_feedback.xml │ │ ├── item_location_text.xml │ │ ├── item_place_suggestion.xml │ │ ├── item_recent_search.xml │ │ ├── item_session.xml │ │ ├── item_social_link.xml │ │ ├── item_speaker.xml │ │ ├── item_sponsor.xml │ │ ├── item_sponsor_detail.xml │ │ ├── item_ticket.xml │ │ ├── item_ticket_details.xml │ │ ├── placeholder_item_card_events.xml │ │ ├── placeholder_item_card_notification.xml │ │ ├── placeholder_item_card_search.xml │ │ ├── placeholder_item_card_similar_events.xml │ │ ├── placeholder_item_card_tickets.xml │ │ ├── placeholder_item_event_location.xml │ │ └── placeholder_item_event_type.xml │ │ ├── menu │ │ ├── event_details.xml │ │ ├── navigation.xml │ │ ├── order_completed.xml │ │ └── order_detail.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── navigation │ │ └── navigation_graph.xml │ │ ├── values-bn-rIN │ │ └── strings.xml │ │ ├── values-hi-rIN │ │ └── strings.xml │ │ ├── values-land │ │ ├── dimens.xml │ │ ├── integers.xml │ │ └── strings.xml │ │ ├── values-sw600dp-land │ │ └── integers.xml │ │ ├── values-sw600dp │ │ ├── dimens.xml │ │ └── integers.xml │ │ ├── values-ur-rPK │ │ └── strings.xml │ │ ├── values-vi │ │ └── strings.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── integers.xml │ │ ├── strings-country-name.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── file_provider.xml │ │ └── settings.xml │ ├── playStore │ └── java │ │ └── org │ │ └── fossasia │ │ └── openevent │ │ └── general │ │ ├── auth │ │ ├── SmartAuthUtil.kt │ │ └── SmartAuthViewModel.kt │ │ └── search │ │ └── location │ │ ├── GeoLocationViewModel.kt │ │ └── LocationServiceImpl.kt │ └── test │ └── java │ └── org │ └── fossasia │ └── openevent │ └── general │ ├── AppLinkUtilsTest.kt │ ├── DependencyTest.kt │ └── event │ └── EventUtilsTest.kt ├── build.gradle ├── docs └── images │ ├── ic_fdroid.png │ └── ic_play_store.png ├── fastlane ├── Appfile ├── Fastfile └── metadata │ └── android │ └── en-US │ ├── changelogs │ ├── 10.txt │ ├── 11.txt │ ├── 12.txt │ ├── 13.txt │ ├── 14.txt │ ├── 15.txt │ ├── 16.txt │ ├── 17.txt │ ├── 6.txt │ ├── 7.txt │ └── 9.txt │ ├── full_description.txt │ ├── images │ ├── icon.png │ └── phoneScreenshots │ │ ├── screenshot_1.jpg │ │ ├── screenshot_2.jpg │ │ ├── screenshot_3.jpg │ │ ├── screenshot_4.jpg │ │ ├── screenshot_5.jpg │ │ ├── screenshot_6.jpg │ │ ├── screenshot_8.jpg │ │ └── screenshot_9.jpg │ ├── short_description.txt │ ├── title.txt │ └── video.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── scripts ├── prep-key.sh ├── secrets.tar.enc └── update-apk.sh └── settings.gradle /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | insert_final_newline = true 7 | 8 | [*.{kt,kts}] 9 | indent_size=4 10 | continuation_indent_size=4 11 | max_line_length=120 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | 9 | 10 | **To Reproduce** 11 | 16 | 17 | **Expected behavior** 18 | 19 | 20 | **Logs** 21 | 22 | 23 | **Screenshots** 24 | 25 | 26 | **Smartphone Info:** 27 | 28 | | | | 29 | |---------------|-| 30 | |Device || 31 | |Android Version| | 32 | 33 | **Additional context** 34 | 35 | 36 | **Would you like to work on the issue?** 37 | 38 | - [ ] Yes 39 | - [ ] No 40 | - Other: 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/chore.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Chore 3 | about: Issues related to docs, workflow, dependency and others 4 | 5 | --- 6 | 7 | **Describe the chore** 8 | 9 | 10 | **Would you like to work on the issue?** 11 | 12 | - [ ] Yes 13 | - [ ] No 14 | - Other: 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Describe the feature you'd like** 8 | 9 | 10 | **Screenshots** 11 | 12 | 13 | **Additional context** 14 | 15 | 16 | **Would you like to work on the issue?** 17 | 18 | - [ ] Yes 19 | - [ ] No 20 | - Other: 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes #[Add issue number here. If you do not solve the issue entirely, please change the message e.g. "First steps for issues #IssueNumber] 2 | 3 | Changes: [Add here what changes were made in this issue and if possible provide links.] 4 | 5 | Screenshots for the change: -------------------------------------------------------------------------------- /.github/auto_label.yml: -------------------------------------------------------------------------------- 1 | labels: [fix, chore, ui] 2 | labelMapping: 3 | feat: [feature] 4 | fix(ui): [fix, ui] 5 | feat(ui): [feat, ui] 6 | refactor: [chore, refactor] 7 | chore(refactor): [chore, refactor] 8 | chore(deps): [dependencies] 9 | chore(docs): [chore, docs] 10 | docs: [chore, docs] 11 | test: [chore, test] 12 | chore(ci): [chore, tools, ci] 13 | chore(tools): [chore, tools] 14 | chore(release): [chore, release] 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gradle 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "21:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: com.stripe:stripe-android 11 | versions: 12 | - 16.2.0 13 | - 16.2.1 14 | - 16.3.0 15 | - 16.3.1 16 | - 16.4.0 17 | - 16.4.1 18 | - 16.4.3 19 | - 16.5.0 20 | - dependency-name: com.fasterxml.jackson.module:jackson-module-kotlin 21 | versions: 22 | - 2.12.1 23 | - 2.12.2 24 | - dependency-name: com.google.android.material:material 25 | versions: 26 | - 1.3.0 27 | - 1.3.0-rc01 28 | - 1.4.0-alpha01 29 | -------------------------------------------------------------------------------- /.github/issue_label_bot.yaml: -------------------------------------------------------------------------------- 1 | label-alias: 2 | bug: 'bug' 3 | feature_request: 'feature' 4 | question: 'question' 5 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: Release v$NEXT_MINOR_VERSION 🌈 2 | tag-template: v$NEXT_MINOR_VERSION 3 | categories: 4 | - title: 🚀 Features 5 | label: feature 6 | - title: 🐛 Bug Fixes 7 | label: fix 8 | - title: 🧰 Maintenance 9 | label: chore 10 | - title: Dependencies and Libraries 11 | label: dependencies 12 | change-template: '- $TITLE (#$NUMBER) - @$AUTHOR' 13 | template: | 14 | ## Changes 15 | 16 | $CHANGES 17 | 18 | ## Contributors 19 | 20 | Thanks a lot to our contributors for making this release possible: 21 | $CONTRIBUTORS 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | dist: trusty 3 | sudo: false 4 | jdk: 5 | - oraclejdk8 6 | android: 7 | components: 8 | - tools 9 | - android-28 10 | - build-tools-28.0.3 11 | - platform-tools 12 | before_cache: 13 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 14 | cache: 15 | directories: 16 | - "${TRAVIS_BUILD_DIR}/gradle/caches/" 17 | - "${TRAVIS_BUILD_DIR}/gradle/wrapper/dists/" 18 | - "$HOME/.gradle/caches/" 19 | - "$HOME/.gradle/wrapper/" 20 | before_script: 21 | - bash scripts/prep-key.sh 22 | script: 23 | - ./gradlew spotlessCheck 24 | - ./gradlew build 25 | after_success: 26 | - bash scripts/update-apk.sh 27 | 28 | branches: 29 | only: 30 | - master 31 | - development 32 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/src/androidTest/java/org/fossasia/openevent/general/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.example.nikit.eventsapp", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/fdroid/java/org/fossasia/openevent/general/auth/SmartAuthUtil.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import android.app.Activity 4 | 5 | object SmartAuthUtil { 6 | fun getCredentialsClient(activity: Activity): Any { 7 | return Unit 8 | } 9 | 10 | fun handleResolvableApiException(rae: Any, activity: Activity, value: Any) { 11 | } 12 | fun getEmailAddressFromIntent(intent: Any?): String? { 13 | return null 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/fdroid/java/org/fossasia/openevent/general/auth/SmartAuthViewModel.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | 7 | const val RC_CREDENTIALS_READ = 2 8 | class SmartAuthViewModel : ViewModel() { 9 | 10 | val mutableId = MutableLiveData() 11 | val id: LiveData = mutableId 12 | private val mutablePassword = MutableLiveData() 13 | val password: LiveData = mutablePassword 14 | private val mutableProgress = MutableLiveData() 15 | val progress: LiveData = mutableProgress 16 | private val mutableApiExceptionRequestCodePair = MutableLiveData>() 17 | val apiExceptionCodePair: LiveData> = mutableApiExceptionRequestCodePair 18 | private val mutableStatus = MutableLiveData() 19 | val isCredentialStored: LiveData = mutableStatus 20 | 21 | fun requestCredentials(any: Any) { 22 | return 23 | } 24 | 25 | fun saveCredential(any1: Any, any2: Any, any3: Any) { 26 | return 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/fdroid/java/org/fossasia/openevent/general/di/FlavorSpecificModules.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.di 2 | 3 | import org.koin.dsl.module 4 | 5 | val flavorSpecificModule = module { } 6 | -------------------------------------------------------------------------------- /app/src/fdroid/java/org/fossasia/openevent/general/search/location/GeoLocationViewModel.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.search.location 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import io.reactivex.disposables.CompositeDisposable 6 | import io.reactivex.rxkotlin.plusAssign 7 | import java.lang.IllegalArgumentException 8 | import org.fossasia.openevent.general.common.SingleLiveEvent 9 | 10 | class GeoLocationViewModel(private val locationService: LocationService) : ViewModel() { 11 | private val mutableLocation = SingleLiveEvent() 12 | val location: LiveData = mutableLocation 13 | private val mutableErrorMessage = SingleLiveEvent() 14 | val errorMessage: SingleLiveEvent = mutableErrorMessage 15 | private val compositeDisposable = CompositeDisposable() 16 | 17 | fun configure() { 18 | compositeDisposable += locationService.getAdministrativeArea() 19 | .subscribe({ 20 | mutableLocation.value = it 21 | }, { 22 | mutableErrorMessage.value = if (it is IllegalArgumentException) "No area found" 23 | else "Something went wrong" 24 | }) 25 | } 26 | 27 | override fun onCleared() { 28 | super.onCleared() 29 | compositeDisposable.clear() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.attendees 2 | 3 | import io.reactivex.Completable 4 | import io.reactivex.Single 5 | import org.fossasia.openevent.general.attendees.forms.CustomForm 6 | import retrofit2.http.Body 7 | import retrofit2.http.DELETE 8 | import retrofit2.http.GET 9 | import retrofit2.http.POST 10 | import retrofit2.http.Path 11 | import retrofit2.http.Query 12 | 13 | interface AttendeeApi { 14 | 15 | @POST("attendees?include=event,ticket&fields[event]=id&fields[ticket]=id") 16 | fun postAttendee(@Body attendee: Attendee): Single 17 | 18 | @DELETE("attendees/{attendeeId}") 19 | fun deleteAttendee(@Path("attendeeId") id: Long): Completable 20 | 21 | @GET("events/{id}/custom-forms") 22 | fun getCustomFormsForAttendees( 23 | @Path("id") id: Long, 24 | @Query("filter") filter: String, 25 | @Query("page[size]") pageSize: Int = 22 26 | ): Single> 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.attendees 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | 7 | class AttendeeConverter { 8 | 9 | @TypeConverter 10 | fun toAttendee(json: String): Attendee? { 11 | return jacksonObjectMapper().readerFor(Attendee::class.java).readValue(json) 12 | } 13 | 14 | @TypeConverter 15 | fun toJson(attendee: Attendee?) = ObjectMapper().writeValueAsString(attendee) 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.attendees 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import io.reactivex.Single 8 | 9 | @Dao 10 | interface AttendeeDao { 11 | @Insert(onConflict = OnConflictStrategy.REPLACE) 12 | fun insertAttendees(attendees: List) 13 | 14 | @Insert(onConflict = OnConflictStrategy.REPLACE) 15 | fun insertAttendee(attendee: Attendee) 16 | 17 | @Query("DELETE FROM Attendee") 18 | fun deleteAllAttendees() 19 | 20 | @Query("SELECT * from Attendee WHERE id in (:ids)") 21 | fun getAttendeesWithIds(ids: List): Single> 22 | 23 | @Query("SELECT * FROM Attendee") 24 | fun getAllAttendees(): Single> 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/attendees/ListAttendeeConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.attendees 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.core.type.TypeReference 5 | import com.fasterxml.jackson.databind.ObjectMapper 6 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 7 | 8 | class ListAttendeeConverter { 9 | 10 | @TypeConverter 11 | fun fromListAttendee(attendees: List): String { 12 | val objectMapper = ObjectMapper() 13 | return objectMapper.writeValueAsString(attendees) 14 | } 15 | 16 | @TypeConverter 17 | fun toListAttendee(attendees: String): List { 18 | val objectMapper = jacksonObjectMapper() 19 | val mapType = object : TypeReference>() {} 20 | return objectMapper.readValue(attendees, mapType) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/attendees/forms/CustomForm.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.attendees.forms 2 | 3 | import androidx.room.Entity 4 | import androidx.room.ForeignKey 5 | import androidx.room.PrimaryKey 6 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 7 | import com.fasterxml.jackson.databind.annotation.JsonNaming 8 | import com.github.jasminb.jsonapi.IntegerIdHandler 9 | import com.github.jasminb.jsonapi.annotations.Id 10 | import com.github.jasminb.jsonapi.annotations.Relationship 11 | import com.github.jasminb.jsonapi.annotations.Type 12 | import org.fossasia.openevent.general.event.Event 13 | import org.fossasia.openevent.general.event.EventId 14 | 15 | @Type("custom-form") 16 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 17 | @Entity(foreignKeys = [(ForeignKey(entity = Event::class, parentColumns = ["id"], 18 | childColumns = ["event"], onDelete = ForeignKey.CASCADE))]) 19 | data class CustomForm( 20 | @Id(IntegerIdHandler::class) 21 | @PrimaryKey 22 | val id: Long, 23 | val form: String, 24 | val fieldIdentifier: String, 25 | val type: String, 26 | val isRequired: Boolean = false, 27 | val isIncluded: Boolean = false, 28 | val isFixed: Boolean? = false, 29 | val ticketsNumber: Int? = null, 30 | @Relationship("event") 31 | var event: EventId? = null 32 | ) 33 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/attendees/forms/FormIdentifier.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.attendees.forms 2 | 3 | object FormIdentifier { 4 | val FIRST_NAME = "firstname" 5 | val LAST_NAME = "lastname" 6 | val EMAIL = "email" 7 | val ADDRESS = "address" 8 | val CITY = "city" 9 | val STATE = "state" 10 | val COUNTRY = "country" 11 | val JOB_TITLE = "jobTitle" 12 | val PHONE = "phone" 13 | val TAX_INFO = "taxBusinessInfo" 14 | val BILLING_ADDRESS = "billingAddress" 15 | val HOME_ADDRESS = "homeAddress" 16 | val SHIPPING_ADDRESS = "shippingAddress" 17 | val COMPANY = "company" 18 | val WORK_ADDRESS = "workAddress" 19 | val WORK_PHONE = "workPhone" 20 | val WEBSITE = "website" 21 | val BLOG = "blog" 22 | val TWITTER = "twitter" 23 | val FACEBOOK = "facebook" 24 | val GITHUB = "github" 25 | val GENDER = "gender" 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/AuthHolder.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import org.fossasia.openevent.general.data.Preference 4 | import org.fossasia.openevent.general.utils.JWTUtils 5 | 6 | private const val TOKEN_KEY = "TOKEN" 7 | 8 | class AuthHolder(private val preference: Preference) { 9 | 10 | var token: String? = null 11 | get() { 12 | return preference.getString(TOKEN_KEY) 13 | } 14 | set(value) { 15 | if (value != null && JWTUtils.isExpired(value)) 16 | throw IllegalStateException("Cannot set expired token") 17 | field = value 18 | preference.putString(TOKEN_KEY, value) 19 | } 20 | 21 | fun getAuthorization(): String? { 22 | if (!isLoggedIn()) 23 | return null 24 | return "JWT $token" 25 | } 26 | 27 | fun isLoggedIn(): Boolean { 28 | if (token == null || JWTUtils.isExpired(token)) { 29 | token = null 30 | return false 31 | } 32 | 33 | return true 34 | } 35 | 36 | fun getId(): Long { 37 | return if (!isLoggedIn()) -1 else JWTUtils.getIdentity(token) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/CheckEmailResponse.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | class CheckEmailResponse( 4 | val result: Boolean 5 | ) 6 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/EmailVerificationResponse.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | class EmailVerificationResponse( 4 | val message: String? = null 5 | ) 6 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/ImageResponse.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | data class ImageResponse(var url: String? = null) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/Login.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | data class Login(val email: String, val password: String) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/LoginResponse.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | 6 | @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class) 7 | data class LoginResponse(val accessToken: String) 8 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/RequestAuthenticator.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import okhttp3.Interceptor 4 | import okhttp3.Response 5 | 6 | class RequestAuthenticator(private val authHolder: AuthHolder) : Interceptor { 7 | 8 | override fun intercept(chain: Interceptor.Chain): Response { 9 | val authorization = authHolder.getAuthorization() 10 | val original = chain.request() 11 | return if (authorization != null) { 12 | val request = original.newBuilder() 13 | .header("Authorization", authorization) 14 | .build() 15 | chain.proceed(request) 16 | } else 17 | chain.proceed(original) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/RequestEmailVerification.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | data class RequestEmailVerification(val data: Token) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/RequestPasswordReset.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import org.fossasia.openevent.general.auth.forgot.PasswordReset 4 | 5 | class RequestPasswordReset( 6 | val data: PasswordReset 7 | ) 8 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/ResetPasswordResponse.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import com.github.jasminb.jsonapi.LongIdHandler 4 | import com.github.jasminb.jsonapi.annotations.Id 5 | 6 | class ResetPasswordResponse( 7 | @Id(LongIdHandler::class) 8 | val id: Long? = null, 9 | val email: String? = null, 10 | val name: String? = null 11 | ) 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/SignUp.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | import com.github.jasminb.jsonapi.IntegerIdHandler 6 | import com.github.jasminb.jsonapi.annotations.Id 7 | import com.github.jasminb.jsonapi.annotations.Type 8 | 9 | @Type("user") 10 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 11 | data class SignUp( 12 | @Id(IntegerIdHandler::class) 13 | val firstName: String? = null, 14 | val lastName: String? = null, 15 | val email: String? = null, 16 | val password: String? = null 17 | ) 18 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/Token.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | data class Token(val token: String) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/UploadImage.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | data class UploadImage(var data: String? = null) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/UserDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy.REPLACE 6 | import androidx.room.Query 7 | import io.reactivex.Single 8 | 9 | @Dao 10 | interface UserDao { 11 | @Insert(onConflict = REPLACE) 12 | fun insertUser(user: User) 13 | 14 | @Query("DELETE FROM User WHERE id = :id") 15 | fun deleteUser(id: Long) 16 | 17 | @Query("SELECT * from User WHERE id = :id") 18 | fun getUser(id: Long): Single 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/UserId.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import com.github.jasminb.jsonapi.IntegerIdHandler 4 | import com.github.jasminb.jsonapi.annotations.Id 5 | import com.github.jasminb.jsonapi.annotations.Type 6 | 7 | @Type("user") 8 | data class UserId( 9 | @Id(IntegerIdHandler::class) 10 | val id: Long 11 | ) 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/UserIdConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import androidx.room.TypeConverter 4 | 5 | class UserIdConverter { 6 | @TypeConverter 7 | fun fromUserId(userId: UserId?): Long? { 8 | return userId?.id 9 | } 10 | 11 | @TypeConverter 12 | fun toUserId(id: Long?): UserId? { 13 | return id?.let { 14 | UserId(it) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/change/ChangeRequestToken.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth.change 2 | 3 | data class ChangeRequestToken(val data: Password) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/change/ChangeRequestTokenResponse.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth.change 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | 6 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 7 | data class ChangeRequestTokenResponse(val email: String, val id: Long, val name: String, val passwordChanged: Boolean) 8 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/change/Password.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth.change 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | 6 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 7 | data class Password(val oldPassword: String, val newPassword: String) 8 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/forgot/Email.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth.forgot 2 | 3 | data class Email(val email: String) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/forgot/PasswordReset.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth.forgot 2 | 3 | class PasswordReset( 4 | val token: String, 5 | val password: String 6 | ) 7 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/forgot/RequestToken.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth.forgot 2 | 3 | data class RequestToken(val data: Email) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/auth/forgot/RequestTokenResponse.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth.forgot 2 | 3 | data class RequestTokenResponse(val message: String) 4 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/common/EventsDiffCallback.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.common 2 | 3 | import androidx.recyclerview.widget.DiffUtil 4 | import org.fossasia.openevent.general.event.Event 5 | 6 | /** 7 | * The DiffUtil ItemCallback class for the [Event] model class. 8 | * This enables proper diffing of items in Recycler Views using [DiffUtil] 9 | */ 10 | class EventsDiffCallback : DiffUtil.ItemCallback() { 11 | 12 | override fun areItemsTheSame(oldItem: Event, newItem: Event): Boolean { 13 | return oldItem.id == newItem.id 14 | } 15 | 16 | override fun areContentsTheSame(oldItem: Event, newItem: Event): Boolean { 17 | return oldItem == newItem 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/connectivity/MutableConnectionLiveData.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.connectivity 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.content.IntentFilter 7 | import android.net.ConnectivityManager 8 | import androidx.lifecycle.MutableLiveData 9 | import org.fossasia.openevent.general.OpenEventGeneral 10 | import org.fossasia.openevent.general.utils.Utils 11 | 12 | class MutableConnectionLiveData : MutableLiveData() { 13 | private val context by lazy { 14 | OpenEventGeneral.appContext 15 | } 16 | 17 | private val broadcastReceiver = object : BroadcastReceiver() { 18 | override fun onReceive(context: Context?, intent: Intent?) { 19 | postValue(Utils.isNetworkConnected(context)) 20 | } 21 | } 22 | 23 | override fun onActive() { 24 | super.onActive() 25 | val intentFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) 26 | context?.registerReceiver(broadcastReceiver, intentFilter) 27 | } 28 | 29 | override fun onInactive() { 30 | super.onInactive() 31 | context?.unregisterReceiver(broadcastReceiver) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/data/Network.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.data 2 | 3 | import android.content.Context 4 | import android.net.ConnectivityManager 5 | import org.fossasia.openevent.general.OpenEventGeneral 6 | 7 | class Network { 8 | 9 | private val context by lazy { 10 | OpenEventGeneral.appContext 11 | } 12 | 13 | private val connectivityManager by lazy { 14 | context?.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager 15 | } 16 | 17 | fun isNetworkConnected(): Boolean { 18 | return connectivityManager?.activeNetworkInfo != null 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/data/Resource.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.data 2 | 3 | import androidx.annotation.ColorRes 4 | import androidx.annotation.StringRes 5 | import org.fossasia.openevent.general.OpenEventGeneral 6 | 7 | class Resource { 8 | 9 | private val context by lazy { 10 | OpenEventGeneral.appContext 11 | } 12 | 13 | fun getString(@StringRes resId: Int) = context?.getString(resId) 14 | 15 | fun getString(@StringRes resId: Int, vararg args: Any?) = context?.getString(resId, args) 16 | 17 | fun getColor(@ColorRes resId: Int) = context?.resources?.getColor(resId) 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/di/HostSelectionInterceptor.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.di 2 | 3 | import okhttp3.HttpUrl.Companion.toHttpUrlOrNull 4 | import okhttp3.Interceptor 5 | import okhttp3.Response 6 | import org.fossasia.openevent.general.BuildConfig 7 | import org.fossasia.openevent.general.data.Preference 8 | import org.fossasia.openevent.general.settings.API_URL 9 | 10 | class HostSelectionInterceptor(private val preference: Preference) : Interceptor { 11 | 12 | override fun intercept(chain: Interceptor.Chain): Response { 13 | var original = chain.request() 14 | val httpUrl = preference.getString(API_URL)?.toHttpUrlOrNull() 15 | if (original.url.host == BuildConfig.DEFAULT_BASE_URL.toHttpUrlOrNull()?.host && httpUrl != null) { 16 | val newUrl = 17 | original.url.newBuilder() 18 | .scheme(httpUrl.scheme) 19 | .host(httpUrl.host) 20 | .port(httpUrl.port) 21 | .build() 22 | original = original.newBuilder() 23 | .url(newUrl) 24 | .build() 25 | } 26 | return chain.proceed(original) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/discount/DiscountApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.discount 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.GET 5 | import retrofit2.http.Path 6 | import retrofit2.http.Query 7 | 8 | interface DiscountApi { 9 | 10 | @GET("events/{eventId}/discount-codes/{code}?include=event,tickets") 11 | fun getDiscountCodes( 12 | @Path("eventId") eventId: Long, 13 | @Path("code") code: String, 14 | @Query("filter") filter: String 15 | ): Single 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/discount/DiscountCode.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.discount 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | import com.github.jasminb.jsonapi.IntegerIdHandler 6 | import com.github.jasminb.jsonapi.annotations.Id 7 | import com.github.jasminb.jsonapi.annotations.Relationship 8 | import com.github.jasminb.jsonapi.annotations.Type 9 | import org.fossasia.openevent.general.event.EventId 10 | import org.fossasia.openevent.general.ticket.TicketId 11 | 12 | @Type("discount-code") 13 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 14 | data class DiscountCode( 15 | @Id(IntegerIdHandler::class) 16 | val id: Int, 17 | val code: String, 18 | val validFrom: String? = null, 19 | val minQuantity: Int? = null, 20 | val createdAt: String? = null, 21 | val ticketsNumber: Int? = null, 22 | val value: Float? = null, 23 | val maxQuantity: Int? = null, 24 | val isActive: Boolean = false, 25 | val usedFor: String, 26 | val validTill: String? = null, 27 | val discountUrl: String? = null, 28 | val type: String, 29 | @Relationship("event") 30 | val eventId: EventId? = null, 31 | @Relationship("tickets") 32 | val tickets: List? = null 33 | ) 34 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/EventApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event 2 | 3 | import io.reactivex.Single 4 | import org.fossasia.openevent.general.sessions.track.Track 5 | import org.fossasia.openevent.general.speakercall.SpeakersCall 6 | import retrofit2.http.GET 7 | import retrofit2.http.Path 8 | import retrofit2.http.Query 9 | 10 | interface EventApi { 11 | 12 | @GET 13 | fun getEvent(id: Long): Single 14 | 15 | @GET("/v1/events/{eventIdentifier}") 16 | fun getEventFromApi(@Path("eventIdentifier") eventIdentifier: String): Single 17 | 18 | @GET("events") 19 | fun eventsWithQuery(@Query("filter") filter: String): Single> 20 | 21 | @GET("events/{eventId}/speakers-call") 22 | fun getSpeakerCallForEvent(@Path("eventId") id: Long): Single 23 | 24 | @GET("events?include=event-sub-topic,event-topic,event-type") 25 | fun searchEventsPaged( 26 | @Query("sort") sort: String, 27 | @Query("filter") eventName: String, 28 | @Query("page[number]") page: Int, 29 | @Query("page[size]") pageSize: Int = 5 30 | ): Single> 31 | 32 | @GET("events") 33 | fun eventsByQuery(@Query("filter") filter: String): Single> 34 | 35 | @GET("events/{eventId}/tracks") 36 | fun fetchTracksUnderEvent(@Path("eventId") eventId: Long): Single> 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/EventId.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event 2 | 3 | import com.github.jasminb.jsonapi.LongIdHandler 4 | import com.github.jasminb.jsonapi.annotations.Id 5 | import com.github.jasminb.jsonapi.annotations.Type 6 | 7 | @Type("event") 8 | data class EventId( 9 | @Id(LongIdHandler::class) 10 | val id: Long 11 | ) 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/EventIdConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event 2 | 3 | import androidx.room.TypeConverter 4 | 5 | class EventIdConverter { 6 | 7 | @TypeConverter 8 | fun fromEventId(eventId: EventId?): Long? { 9 | return eventId?.id 10 | } 11 | 12 | @TypeConverter 13 | fun toEventId(id: Long?): EventId? { 14 | return id?.let { 15 | EventId(it) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/faq/EventFAQ.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.faq 2 | 3 | import com.github.jasminb.jsonapi.LongIdHandler 4 | import com.github.jasminb.jsonapi.annotations.Id 5 | import com.github.jasminb.jsonapi.annotations.Type 6 | 7 | @Type("faq") 8 | data class EventFAQ( 9 | @Id(LongIdHandler::class) 10 | val id: Long, 11 | val question: String, 12 | val answer: String 13 | ) 14 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/faq/EventFAQApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.faq 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.GET 5 | import retrofit2.http.Path 6 | 7 | interface EventFAQApi { 8 | 9 | @GET("events/{id}/faqs?sort=question") 10 | fun getEventFAQ(@Path("id") id: Long): Single> 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/faq/FAQRecyclerAdapter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.faq 2 | 3 | import android.view.LayoutInflater 4 | import android.view.ViewGroup 5 | import androidx.recyclerview.widget.RecyclerView 6 | import org.fossasia.openevent.general.R 7 | 8 | class FAQRecyclerAdapter : RecyclerView.Adapter() { 9 | val faqList = ArrayList() 10 | 11 | fun addAll(faqList: List) { 12 | if (faqList.isNotEmpty()) 13 | this.faqList.clear() 14 | this.faqList.addAll(faqList) 15 | notifyDataSetChanged() 16 | } 17 | 18 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FAQViewHolder { 19 | val view = LayoutInflater.from(parent.context).inflate(R.layout.item_faq, parent, false) 20 | return FAQViewHolder(view) 21 | } 22 | 23 | override fun onBindViewHolder(holder: FAQViewHolder, position: Int) { 24 | val faq = faqList[position] 25 | 26 | holder.bind(faq) 27 | } 28 | 29 | override fun getItemCount(): Int { 30 | return faqList.size 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/faq/FAQViewHolder.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.faq 2 | 3 | import android.view.View 4 | import androidx.recyclerview.widget.RecyclerView 5 | import kotlinx.android.synthetic.main.item_faq.view.answerTv 6 | import kotlinx.android.synthetic.main.item_faq.view.questiontv 7 | 8 | class FAQViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 9 | 10 | fun bind(faq: EventFAQ) { 11 | itemView.questiontv.text = faq.question 12 | itemView.answerTv.text = faq.answer 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/location/EventLocation.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.location 2 | 3 | import com.github.jasminb.jsonapi.LongIdHandler 4 | import com.github.jasminb.jsonapi.annotations.Id 5 | import com.github.jasminb.jsonapi.annotations.Type 6 | 7 | @Type("event-location") 8 | data class EventLocation( 9 | @Id(LongIdHandler::class) 10 | val id: Long, 11 | val name: String, 12 | val slug: String 13 | ) 14 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/location/EventLocationApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.location 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.GET 5 | 6 | interface EventLocationApi { 7 | 8 | @GET("event-locations?sort=name") 9 | fun getEventLocation(): Single> 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/paging/EventsDataSourceFactory.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.paging 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.paging.DataSource 5 | import io.reactivex.disposables.CompositeDisposable 6 | import org.fossasia.openevent.general.event.Event 7 | import org.fossasia.openevent.general.event.EventService 8 | 9 | class EventsDataSourceFactory( 10 | private val compositeDisposable: CompositeDisposable, 11 | private val eventService: EventService, 12 | private val query: String?, 13 | private val mutableProgress: MutableLiveData 14 | ) : DataSource.Factory() { 15 | override fun create(): DataSource { 16 | return EventsDataSource( 17 | eventService, 18 | compositeDisposable, 19 | query, 20 | mutableProgress 21 | ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/paging/SimilarEventsDataSourceFactory.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.paging 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.paging.DataSource 5 | import io.reactivex.disposables.CompositeDisposable 6 | import org.fossasia.openevent.general.event.Event 7 | import org.fossasia.openevent.general.event.EventService 8 | 9 | class SimilarEventsDataSourceFactory( 10 | private val compositeDisposable: CompositeDisposable, 11 | private val topicId: Long, 12 | private val location: String?, 13 | private val eventId: Long, 14 | private val mutableProgress: MutableLiveData, 15 | private val eventService: EventService 16 | ) : DataSource.Factory() { 17 | override fun create(): DataSource { 18 | return SimilarEventsDataSource( 19 | compositeDisposable, topicId, location, eventId, mutableProgress, eventService 20 | ) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/subtopic/EventSubTopic.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.subtopic 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.PrimaryKey 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Relationship 10 | import com.github.jasminb.jsonapi.annotations.Type 11 | import org.fossasia.openevent.general.event.Event 12 | import org.fossasia.openevent.general.event.EventId 13 | 14 | @Type("event-sub-topic") 15 | @Entity(foreignKeys = [(ForeignKey(entity = Event::class, parentColumns = ["id"], 16 | childColumns = ["event"], onDelete = ForeignKey.CASCADE))]) 17 | data class EventSubTopic( 18 | @Id(LongIdHandler::class) 19 | @PrimaryKey 20 | val id: Long, 21 | val name: String, 22 | val slug: String, 23 | @ColumnInfo(index = true) 24 | @Relationship("event") 25 | var event: EventId? = null 26 | ) 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/subtopic/EventSubTopicConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.subtopic 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | 7 | class EventSubTopicConverter { 8 | 9 | @TypeConverter 10 | fun toEventSubTopic(json: String): EventSubTopic? { 11 | return jacksonObjectMapper().readerFor(EventSubTopic::class.java).readValue(json) 12 | } 13 | 14 | @TypeConverter 15 | fun toJson(eventSubTopic: EventSubTopic?) = ObjectMapper().writeValueAsString(eventSubTopic) 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/tax/Tax.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.tax 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 7 | import com.fasterxml.jackson.databind.annotation.JsonNaming 8 | import com.github.jasminb.jsonapi.IntegerIdHandler 9 | import com.github.jasminb.jsonapi.annotations.Id 10 | import com.github.jasminb.jsonapi.annotations.Relationship 11 | import com.github.jasminb.jsonapi.annotations.Type 12 | import org.fossasia.openevent.general.event.EventId 13 | 14 | @Type("tax") 15 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 16 | @Entity 17 | class Tax( 18 | @Id(IntegerIdHandler::class) 19 | @PrimaryKey 20 | val id: Int? = null, 21 | val name: String? = null, 22 | val rate: Float? = null, 23 | val taxId: String? = null, 24 | val registeredCompany: String? = null, 25 | val address: String? = null, 26 | val city: String? = null, 27 | val stare: String? = null, 28 | val zip: String? = null, 29 | val invoiceFooter: String? = null, 30 | val isInvoiceSend: Boolean = false, 31 | val isTaxIncludedInPrice: Boolean = false, 32 | val shouldSendInvoice: Boolean = false, 33 | @ColumnInfo(index = true) 34 | @Relationship("event") 35 | val eventId: EventId? = null 36 | ) 37 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/tax/TaxApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.tax 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.GET 5 | import retrofit2.http.Path 6 | 7 | interface TaxApi { 8 | 9 | @GET("events/{event_identifier}/tax?include=event") 10 | fun getTaxDetails(@Path("event_identifier") identifier: String): Single 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/tax/TaxDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.tax 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import io.reactivex.Single 8 | 9 | @Dao 10 | interface TaxDao { 11 | 12 | @Insert(onConflict = OnConflictStrategy.REPLACE) 13 | fun insertTax(tax: Tax) 14 | 15 | @Query("SELECT * from Tax WHERE eventId = :eventId") 16 | fun getTaxDetails(eventId: Long): Single 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/tax/TaxService.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.tax 2 | 3 | import io.reactivex.Single 4 | import timber.log.Timber 5 | 6 | class TaxService( 7 | private val taxApi: TaxApi, 8 | private val taxDao: TaxDao 9 | ) { 10 | 11 | fun getTax(eventId: Long): Single { 12 | return taxApi.getTaxDetails(eventId.toString()) 13 | .onErrorResumeNext { 14 | Timber.e(it, "Error fetching tax") 15 | taxDao.getTaxDetails(eventId) 16 | }.map { 17 | taxDao.insertTax(it) 18 | it 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/topic/EventTopic.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.topic 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.PrimaryKey 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Relationship 10 | import com.github.jasminb.jsonapi.annotations.Type 11 | import org.fossasia.openevent.general.event.Event 12 | import org.fossasia.openevent.general.event.EventId 13 | 14 | @Type("event-topic") 15 | @Entity(foreignKeys = [(ForeignKey(entity = Event::class, parentColumns = ["id"], 16 | childColumns = ["event"], onDelete = ForeignKey.CASCADE))]) 17 | data class EventTopic( 18 | @Id(LongIdHandler::class) 19 | @PrimaryKey 20 | val id: Long, 21 | val name: String, 22 | val slug: String, 23 | @ColumnInfo(index = true) 24 | @Relationship("event") 25 | var event: EventId? = null 26 | ) 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/topic/EventTopicApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.topic 2 | 3 | import io.reactivex.Single 4 | import org.fossasia.openevent.general.event.Event 5 | import retrofit2.http.GET 6 | import retrofit2.http.Path 7 | import retrofit2.http.Query 8 | 9 | interface EventTopicApi { 10 | 11 | @GET("event-topics/{id}/events?include=event-topic") 12 | fun getEventsUnderTopicIdPaged( 13 | @Path("id") id: Long, 14 | @Query("filter") filter: String, 15 | @Query("page[number]") page: Int, 16 | @Query("page[size]") pageSize: Int = 5 17 | ): Single> 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/topic/EventTopicConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.topic 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | 7 | class EventTopicConverter { 8 | @TypeConverter 9 | fun toEventTopic(json: String): EventTopic? { 10 | return jacksonObjectMapper().readerFor(EventTopic::class.java).readValue(json) 11 | } 12 | 13 | @TypeConverter 14 | fun toJson(eventTopic: EventTopic?) = ObjectMapper().writeValueAsString(eventTopic) 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/topic/EventTopicsDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.topic 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import io.reactivex.Flowable 8 | 9 | @Dao 10 | interface EventTopicsDao { 11 | 12 | @Insert(onConflict = OnConflictStrategy.REPLACE) 13 | fun insertEventTopics(eventTopic: List) 14 | 15 | @Query("SELECT * from EventTopic") 16 | fun getAllEventTopics(): Flowable> 17 | 18 | @Query("DELETE FROM EventTopic") 19 | fun deleteAll() 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/types/EventType.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.types 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | import com.github.jasminb.jsonapi.LongIdHandler 7 | import com.github.jasminb.jsonapi.annotations.Id 8 | import com.github.jasminb.jsonapi.annotations.Relationship 9 | import com.github.jasminb.jsonapi.annotations.Type 10 | import org.fossasia.openevent.general.event.EventId 11 | 12 | @Type("event-type") 13 | @Entity 14 | data class EventType( 15 | @Id(LongIdHandler::class) 16 | @PrimaryKey 17 | val id: Long, 18 | val name: String, 19 | val slug: String, 20 | @ColumnInfo(index = true) 21 | @Relationship("event") 22 | var event: EventId? = null 23 | ) 24 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/types/EventTypeConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.types 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | 7 | class EventTypeConverter { 8 | @TypeConverter 9 | fun toEventType(json: String): EventType? { 10 | return jacksonObjectMapper().readerFor(EventType::class.java).readValue(json) 11 | } 12 | 13 | @TypeConverter 14 | fun toJson(eventType: EventType?) = ObjectMapper().writeValueAsString(eventType) 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/event/types/EventTypesApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.event.types 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.GET 5 | 6 | interface EventTypesApi { 7 | 8 | @GET("event-types?sort=name") 9 | fun getEventTypes(): Single> 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/favorite/FavoriteEvent.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.favorite 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Relationship 10 | import com.github.jasminb.jsonapi.annotations.Type 11 | import org.fossasia.openevent.general.event.EventId 12 | 13 | @Type("user-favourite-event") 14 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 15 | data class FavoriteEvent( 16 | @Id(LongIdHandler::class) 17 | @PrimaryKey 18 | val id: Long, 19 | @ColumnInfo(index = true) 20 | @Relationship("event", resolve = true) 21 | val event: EventId? = null 22 | ) 23 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/favorite/FavoriteEventApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.favorite 2 | 3 | import io.reactivex.Completable 4 | import io.reactivex.Single 5 | import retrofit2.http.Body 6 | import retrofit2.http.DELETE 7 | import retrofit2.http.GET 8 | import retrofit2.http.Header 9 | import retrofit2.http.POST 10 | import retrofit2.http.Path 11 | 12 | interface FavoriteEventApi { 13 | @GET("user-favourite-events?include=event") 14 | fun getFavorites(): Single> 15 | 16 | @POST("user-favourite-events") 17 | fun addFavorite( 18 | @Body favorite: FavoriteEvent, 19 | @Header("Content-Type") header: String = "application/vnd.api+json" 20 | ): Single 21 | 22 | @DELETE("user-favourite-events/{favoriteEventId}") 23 | fun removeFavorite( 24 | @Path("favoriteEventId") eventId: Long, 25 | @Header("Content-Type") header: String = "application/vnd.api+json" 26 | ): Completable 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/feedback/Feedback.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.feedback 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Relationship 10 | import com.github.jasminb.jsonapi.annotations.Type 11 | import org.fossasia.openevent.general.auth.UserId 12 | import org.fossasia.openevent.general.event.EventId 13 | 14 | @Type("feedback") 15 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 16 | @Entity 17 | data class Feedback( 18 | @Id(LongIdHandler::class) 19 | @PrimaryKey 20 | val id: Long? = null, 21 | val rating: String?, 22 | val comment: String?, 23 | @Relationship("event") 24 | var event: EventId? = null, 25 | @Relationship("user") 26 | var user: UserId? = null 27 | ) 28 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/feedback/FeedbackApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.feedback 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.Body 5 | import retrofit2.http.GET 6 | import retrofit2.http.POST 7 | import retrofit2.http.Path 8 | import retrofit2.http.Query 9 | 10 | interface FeedbackApi { 11 | 12 | @GET("events/{eventId}/feedbacks?include=event") 13 | fun getEventFeedback( 14 | @Path("eventId") eventId: Long, 15 | @Query("sort") sort: String = "rating", 16 | @Query("filter") eventName: String = "[]" 17 | ): Single> 18 | 19 | @POST("feedbacks") 20 | fun postfeedback(@Body feedback: Feedback): Single 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/feedback/FeedbackDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.feedback 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy.REPLACE 6 | import androidx.room.Query 7 | import io.reactivex.Single 8 | 9 | @Dao 10 | interface FeedbackDao { 11 | 12 | @Insert(onConflict = REPLACE) 13 | fun insertFeedback(feedbacks: List) 14 | 15 | @Insert(onConflict = REPLACE) 16 | fun insertSingleFeedback(feedback: Feedback) 17 | 18 | @Query("SELECT * FROM feedback WHERE event = :eventId") 19 | fun getAllFeedbackUnderEvent(eventId: Long): Single> 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/feedback/FeedbackService.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.feedback 2 | 3 | import io.reactivex.Single 4 | 5 | class FeedbackService( 6 | private val feedbackDao: FeedbackDao, 7 | private val feedbackApi: FeedbackApi 8 | ) { 9 | fun getFeedbackUnderEventFromDb(eventId: Long): Single> = 10 | feedbackDao.getAllFeedbackUnderEvent(eventId) 11 | 12 | fun getEventFeedback(id: Long): Single> = 13 | feedbackApi.getEventFeedback(id).doOnSuccess { 14 | feedbackDao.insertFeedback(it) 15 | } 16 | 17 | fun submitFeedback(feedback: Feedback): Single = 18 | feedbackApi.postfeedback(feedback).doOnSuccess { 19 | feedbackDao.insertSingleFeedback(it) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/feedback/FeedbackViewHolder.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.feedback 2 | 3 | import android.view.View 4 | import androidx.recyclerview.widget.RecyclerView 5 | import kotlinx.android.synthetic.main.item_feedback.view.commentTv 6 | import kotlinx.android.synthetic.main.item_feedback.view.ratingBar 7 | 8 | const val MAX_COMMENT_LINE = 3 9 | 10 | class FeedbackViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 11 | 12 | fun bind(feedback: Feedback) { 13 | itemView.commentTv.text = feedback.comment 14 | itemView.ratingBar.rating = feedback.rating?.toFloat() ?: 0f 15 | 16 | itemView.commentTv.setOnClickListener { 17 | itemView.commentTv.maxLines = 18 | if (itemView.commentTv.maxLines == MAX_COMMENT_LINE) Int.MAX_VALUE else MAX_COMMENT_LINE 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/location/LocationExceptions.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.location 2 | 3 | /** 4 | * Thrown when there isn't a location source available. 5 | * */ 6 | class NoLocationSourceException : Exception() 7 | 8 | /** 9 | * Thrown when the user hasn't granted permission necessary to complete an action. 10 | * */ 11 | class LocationPermissionException : Exception() 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/notification/Notification.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.notification 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.annotation.JsonProperty 6 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 7 | import com.fasterxml.jackson.databind.annotation.JsonNaming 8 | import com.github.jasminb.jsonapi.IntegerIdHandler 9 | import com.github.jasminb.jsonapi.annotations.Id 10 | import com.github.jasminb.jsonapi.annotations.Type 11 | import io.reactivex.annotations.NonNull 12 | 13 | @Type("notification") 14 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 15 | @Entity 16 | data class Notification( 17 | @Id(IntegerIdHandler::class) 18 | @NonNull 19 | @PrimaryKey 20 | val id: Int, 21 | val message: String? = null, 22 | val receivedAt: String? = null, 23 | @get:JsonProperty("is-read") 24 | var isRead: Boolean = false, 25 | val title: String? = null, 26 | val deletedAt: String? = null 27 | ) 28 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/notification/NotificationApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.notification 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.Body 5 | import retrofit2.http.GET 6 | import retrofit2.http.PATCH 7 | import retrofit2.http.Path 8 | 9 | interface NotificationApi { 10 | 11 | @GET("users/{userId}/notifications?sort=received-at") 12 | fun getNotifications(@Path("userId") userId: Long): Single> 13 | 14 | @PATCH("notifications/{notification_id}") 15 | fun updateNotification( 16 | @Path("notification_id") notificationId: Int, 17 | @Body notification: Notification 18 | ): Single 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/notification/NotificationDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.notification 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy.REPLACE 6 | import androidx.room.Query 7 | import io.reactivex.Single 8 | 9 | @Dao 10 | interface NotificationDao { 11 | @Insert(onConflict = REPLACE) 12 | fun insertNotifications(notifications: List) 13 | 14 | @Insert(onConflict = REPLACE) 15 | fun insertNotification(notification: Notification) 16 | 17 | @Query("SELECT * FROM Notification") 18 | fun getNotifications(): Single> 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/notification/NotificationService.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.notification 2 | 3 | import io.reactivex.Single 4 | 5 | class NotificationService( 6 | private val notificationApi: NotificationApi, 7 | private val notificationDao: NotificationDao 8 | ) { 9 | 10 | fun getNotifications(userId: Long): Single> { 11 | return notificationDao.getNotifications() 12 | .onErrorResumeNext { 13 | notificationApi.getNotifications(userId).map { 14 | notificationDao.insertNotifications(it) 15 | it 16 | } 17 | } 18 | } 19 | 20 | fun syncNotifications(userId: Long): Single> { 21 | return notificationApi.getNotifications(userId).map { 22 | notificationDao.insertNotifications(it) 23 | it 24 | } 25 | } 26 | 27 | fun updateNotification(notification: Notification): Single { 28 | return notificationApi.updateNotification(notification.id, notification).map { 29 | notificationDao.insertNotification(it) 30 | it 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/notification/NotificationsRecyclerAdapter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.notification 2 | 3 | import android.view.LayoutInflater 4 | import android.view.ViewGroup 5 | import androidx.recyclerview.widget.RecyclerView 6 | import org.fossasia.openevent.general.R 7 | 8 | class NotificationsRecyclerAdapter : RecyclerView.Adapter() { 9 | 10 | private val notificationList = ArrayList() 11 | 12 | fun addAll(list: List) { 13 | notificationList.clear() 14 | notificationList.addAll(list) 15 | } 16 | 17 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotificationsViewHolder { 18 | val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_notification, parent, false) 19 | return NotificationsViewHolder(view) 20 | } 21 | 22 | override fun onBindViewHolder(holder: NotificationsViewHolder, position: Int) { 23 | holder.bind(notificationList[position]) 24 | } 25 | 26 | override fun getItemCount(): Int { 27 | return notificationList.size 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/notification/NotificationsViewHolder.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.notification 2 | 3 | import android.text.Html 4 | import android.text.method.LinkMovementMethod 5 | import android.view.View 6 | import androidx.recyclerview.widget.RecyclerView 7 | import kotlinx.android.synthetic.main.item_card_notification.view.* 8 | import org.fossasia.openevent.general.event.EventUtils 9 | 10 | class NotificationsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 11 | 12 | fun bind( 13 | notification: Notification 14 | 15 | ) { 16 | itemView.title.text = notification.title 17 | itemView.message.movementMethod = LinkMovementMethod.getInstance() 18 | itemView.message.text = Html.fromHtml(notification.message) 19 | notification.receivedAt?.let { 20 | val dayDiff = EventUtils.getDayDifferenceFromToday(it) 21 | val formattedDateTime = EventUtils.getEventDateTime(it) 22 | itemView.time.text = when (dayDiff) { 23 | 0L -> EventUtils.getFormattedTime(formattedDateTime) 24 | in 1..6 -> EventUtils.getFormattedWeekDay(formattedDateTime) 25 | else -> EventUtils.getFormattedDateWithoutWeekday(formattedDateTime) 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/order/Charge.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.order 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | import com.github.jasminb.jsonapi.IntegerIdHandler 6 | import com.github.jasminb.jsonapi.annotations.Id 7 | import com.github.jasminb.jsonapi.annotations.Type 8 | 9 | @Type("charge") 10 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 11 | data class Charge( 12 | @Id(IntegerIdHandler::class) 13 | val id: Int, 14 | val stripe: String? = null, 15 | val paypal: String? = null, 16 | val paypalPayerId: String? = null, 17 | val paypalPaymentId: String? = null, 18 | val message: String? = null, 19 | val status: Boolean? = null 20 | ) 21 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/order/ConfirmOrder.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.order 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | import com.github.jasminb.jsonapi.annotations.Id 6 | import com.github.jasminb.jsonapi.annotations.Type 7 | 8 | @Type("order") 9 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 10 | data class ConfirmOrder( 11 | @Id 12 | val id: String, 13 | val status: String? = null, 14 | val orderNotes: String? = null 15 | ) 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/order/OrderDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.order 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import io.reactivex.Single 8 | 9 | @Dao 10 | interface OrderDao { 11 | @Insert(onConflict = OnConflictStrategy.REPLACE) 12 | fun insertOrders(orders: List) 13 | 14 | @Insert(onConflict = OnConflictStrategy.REPLACE) 15 | fun insertOrder(order: Order) 16 | 17 | @Query("SELECT * FROM `order`") 18 | fun getAllOrders(): Single> 19 | 20 | @Query("SELECT * FROM `order` WHERE isExpired = :expired") 21 | fun getOrders(expired: Boolean): Single> 22 | 23 | @Query("DELETE FROM `order`") 24 | fun deleteAllOrders() 25 | 26 | @Query("SELECT * FROM `order` WHERE id = :orderId") 27 | fun getOrderById(orderId: Long): Single 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/order/QrCode.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.order 2 | 3 | import android.graphics.Bitmap 4 | import com.google.zxing.BarcodeFormat 5 | import com.google.zxing.EncodeHintType 6 | import com.google.zxing.MultiFormatWriter 7 | import com.google.zxing.WriterException 8 | import com.journeyapps.barcodescanner.BarcodeEncoder 9 | import timber.log.Timber 10 | 11 | class QrCode { 12 | private val multiFormatWriter = MultiFormatWriter() 13 | private val barcodeEncoder = BarcodeEncoder() 14 | 15 | fun generateQrBitmap(text: String?, width: Int, height: Int): Bitmap? { 16 | try { 17 | val hint = HashMap() 18 | hint[EncodeHintType.MARGIN] = 1 19 | val bitMatrix = multiFormatWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hint) 20 | return barcodeEncoder.createBitmap(bitMatrix) 21 | } catch (e: WriterException) { 22 | Timber.d(e, "Writer Exception") 23 | } 24 | return null 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/paypal/Paypal.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.paypal 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | import com.github.jasminb.jsonapi.annotations.Id 6 | import com.github.jasminb.jsonapi.annotations.Type 7 | 8 | @Type("order") 9 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 10 | class Paypal( 11 | @Id 12 | val id: Int? = null, 13 | val paymentId: String 14 | ) 15 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/paypal/PaypalApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.paypal 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.Body 5 | import retrofit2.http.POST 6 | import retrofit2.http.Path 7 | 8 | interface PaypalApi { 9 | 10 | @POST("orders/{orderIdentifier}/verify-mobile-paypal-payment") 11 | fun verifyPaypalPayment( 12 | @Path("orderIdentifier") orderIdentifier: String, 13 | @Body paypal: Paypal 14 | ): Single 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/paypal/PaypalPaymentResponse.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.paypal 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming 5 | 6 | @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class) 7 | data class PaypalPaymentResponse( 8 | val status: Boolean, 9 | val error: String? = null 10 | ) 11 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/search/SearchEventsDataSourceFactory.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.search 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.paging.DataSource 5 | import io.reactivex.disposables.CompositeDisposable 6 | import org.fossasia.openevent.general.event.Event 7 | import org.fossasia.openevent.general.event.EventService 8 | 9 | data class SearchEventsDataSourceFactory( 10 | private val compositeDisposable: CompositeDisposable, 11 | private val eventService: EventService, 12 | private val query: String, 13 | private val sortBy: String, 14 | private val mutableProgress: MutableLiveData 15 | ) : DataSource.Factory() { 16 | override fun create(): DataSource { 17 | return SearchEventsDataSource( 18 | eventService, 19 | compositeDisposable, 20 | query, 21 | sortBy, 22 | mutableProgress 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/search/location/LocationService.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.search.location 2 | 3 | import io.reactivex.Single 4 | 5 | /** 6 | * Implementations of this interface provide functionality related to the user location. 7 | * */ 8 | interface LocationService { 9 | 10 | /** 11 | * Gives the administrative area of the current location the user is in. 12 | * */ 13 | fun getAdministrativeArea(): Single 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/search/location/LocationViewHolder.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.search.location 2 | 3 | import android.view.View 4 | import androidx.recyclerview.widget.RecyclerView 5 | import kotlinx.android.synthetic.main.item_location_text.view.locationText 6 | 7 | class LocationViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 8 | 9 | fun bind(location: String, listener: TextClickListener?) { 10 | itemView.locationText.text = location 11 | itemView.setOnClickListener { 12 | listener?.onTextClick(location) 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/search/recentsearch/RecentSearchViewHolder.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.search.recentsearch 2 | 3 | import android.view.View 4 | import androidx.recyclerview.widget.RecyclerView 5 | import kotlinx.android.synthetic.main.item_recent_search.view.clearRecent 6 | import kotlinx.android.synthetic.main.item_recent_search.view.recentSearchLocation 7 | import kotlinx.android.synthetic.main.item_recent_search.view.recentSearchText 8 | 9 | class RecentSearchViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 10 | 11 | fun bind( 12 | searches: Pair, 13 | position: Int, 14 | listener: RecentSearchListener? 15 | ) { 16 | itemView.recentSearchText.text = searches.first 17 | itemView.recentSearchLocation.text = searches.second 18 | itemView.setOnClickListener { 19 | listener?.clickSearch(searches.first, searches.second) 20 | } 21 | itemView.clearRecent.setOnClickListener { 22 | listener?.removeSearch(position, searches) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/search/time/SearchTimeViewModel.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.search.time 2 | 3 | import androidx.lifecycle.ViewModel 4 | import org.fossasia.openevent.general.data.Preference 5 | 6 | const val SAVED_TIME = "TIME" 7 | 8 | class SearchTimeViewModel(private val preference: Preference) : ViewModel() { 9 | 10 | fun saveTime(query: String) { 11 | preference.putString(SAVED_TIME, query) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sessions/SessionDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sessions 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Insert 6 | import androidx.room.OnConflictStrategy.REPLACE 7 | import androidx.room.Query 8 | import io.reactivex.Flowable 9 | 10 | @Dao 11 | interface SessionDao { 12 | 13 | @Insert(onConflict = REPLACE) 14 | fun insertSessions(sessions: List) 15 | 16 | @Insert(onConflict = REPLACE) 17 | fun insertSession(session: Session) 18 | 19 | @Query("SELECT * FROM Session WHERE id =:id") 20 | fun getSessionById(id: Long): Flowable 21 | 22 | @Query("SELECT * FROM Session") 23 | fun getAllSessions(): LiveData> 24 | 25 | @Query("DELETE FROM Session") 26 | fun deleteCurrentSessions() 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sessions/SessionRecyclerAdapter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sessions 2 | 3 | import android.view.LayoutInflater 4 | import android.view.ViewGroup 5 | import androidx.recyclerview.widget.RecyclerView 6 | import org.fossasia.openevent.general.R 7 | import org.fossasia.openevent.general.common.SessionClickListener 8 | 9 | class SessionRecyclerAdapter : RecyclerView.Adapter() { 10 | private val sessionList = ArrayList() 11 | var onSessionClick: SessionClickListener? = null 12 | 13 | fun addAll(sessionList: List) { 14 | if (sessionList.isNotEmpty()) 15 | this.sessionList.clear() 16 | this.sessionList.addAll(sessionList) 17 | notifyDataSetChanged() 18 | } 19 | 20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SessionViewHolder { 21 | val view = LayoutInflater.from(parent.context).inflate(R.layout.item_session, parent, false) 22 | return SessionViewHolder(view) 23 | } 24 | 25 | override fun onBindViewHolder(holder: SessionViewHolder, position: Int) { 26 | val session = sessionList[position] 27 | 28 | holder.apply { 29 | bind(session) 30 | sessionClickListener = onSessionClick 31 | } 32 | } 33 | 34 | override fun getItemCount(): Int { 35 | return sessionList.size 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sessions/microlocation/MicroLocation.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sessions.microlocation 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Type 10 | 11 | @Type("microlocation") 12 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 13 | @Entity 14 | data class MicroLocation( 15 | @Id(LongIdHandler::class) 16 | @PrimaryKey 17 | val id: Long, 18 | val name: String, 19 | val room: String?, 20 | val latitude: String?, 21 | val longitude: String?, 22 | val floor: String?, 23 | val deletedAt: String? 24 | ) 25 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sessions/microlocation/MicroLocationConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sessions.microlocation 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | 7 | class MicroLocationConverter { 8 | @TypeConverter 9 | fun toMicroLoation(json: String) = 10 | jacksonObjectMapper().readerFor(MicroLocation::class.java).readValue(json) 11 | 12 | @TypeConverter 13 | fun toJson(microLocation: MicroLocation?) = ObjectMapper().writeValueAsString(microLocation) 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sessions/sessiontype/SessionType.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sessions.sessiontype 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Type 10 | 11 | @Type("session-type") 12 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 13 | @Entity 14 | data class SessionType( 15 | @Id(LongIdHandler::class) 16 | @PrimaryKey 17 | val id: Long, 18 | val name: String, 19 | val length: String?, 20 | val deletedAt: String? 21 | ) 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sessions/sessiontype/SessionTypeConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sessions.sessiontype 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | 7 | class SessionTypeConverter { 8 | 9 | @TypeConverter 10 | fun toSessionType(json: String): SessionType? = 11 | jacksonObjectMapper().readerFor(SessionType::class.java).readValue(json) 12 | 13 | @TypeConverter 14 | fun toJson(sessionType: SessionType?) = ObjectMapper().writeValueAsString(sessionType) 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sessions/track/Track.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sessions.track 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Type 10 | 11 | @Type("track") 12 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 13 | @Entity 14 | data class Track( 15 | @Id(LongIdHandler::class) 16 | @PrimaryKey 17 | val id: Long, 18 | val name: String, 19 | val description: String?, 20 | val color: String, 21 | val fontColor: String? 22 | ) 23 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sessions/track/TrackConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sessions.track 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | 7 | class TrackConverter { 8 | 9 | @TypeConverter 10 | fun toTrack(json: String): Track? = 11 | jacksonObjectMapper().readerFor(Track::class.java).readValue(json) 12 | 13 | @TypeConverter 14 | fun toJson(track: Track?) = ObjectMapper().writeValueAsString(track) 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/settings/Settings.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.settings 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming 7 | import com.github.jasminb.jsonapi.IntegerIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Type 10 | 11 | @Type("setting") 12 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 13 | @Entity 14 | data class Settings( 15 | @Id(IntegerIdHandler::class) 16 | @PrimaryKey 17 | val id: Int? = null, 18 | val appName: String? = null, 19 | val tagline: String? = null, 20 | val isPaypalActivated: Boolean = false, 21 | val isStripeActivated: Boolean = false, 22 | val isOmiseActivated: Boolean = false, 23 | val frontendUrl: String? = null, 24 | val cookiePolicy: String? = null, 25 | val cookiePolicyLink: String? = null, 26 | val orderExpiryTime: Int? = null 27 | ) 28 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/settings/SettingsApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.settings 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.GET 5 | 6 | interface SettingsApi { 7 | 8 | @GET("settings") 9 | fun getSettings(): Single 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/settings/SettingsDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.settings 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy.REPLACE 6 | import androidx.room.Query 7 | import io.reactivex.Single 8 | 9 | @Dao 10 | interface SettingsDao { 11 | 12 | @Insert(onConflict = REPLACE) 13 | fun insertSettings(settings: Settings) 14 | 15 | @Query("SELECT * FROM Settings") 16 | fun getSettings(): Single 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/settings/SettingsService.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.settings 2 | 3 | import io.reactivex.Single 4 | 5 | class SettingsService( 6 | private val settingsApi: SettingsApi, 7 | private val settingsDao: SettingsDao 8 | ) { 9 | 10 | fun fetchSettings(): Single { 11 | return settingsApi.getSettings().map { 12 | settingsDao.insertSettings(it) 13 | it 14 | }.flatMap { 15 | settingsDao.getSettings() 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/social/SocialLink.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.social 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.ForeignKey.CASCADE 7 | import androidx.room.PrimaryKey 8 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 9 | import com.fasterxml.jackson.databind.annotation.JsonNaming 10 | import com.github.jasminb.jsonapi.IntegerIdHandler 11 | import com.github.jasminb.jsonapi.annotations.Id 12 | import com.github.jasminb.jsonapi.annotations.Relationship 13 | import com.github.jasminb.jsonapi.annotations.Type 14 | import org.fossasia.openevent.general.event.Event 15 | import org.fossasia.openevent.general.event.EventId 16 | 17 | @Type("social-link") 18 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 19 | @Entity(foreignKeys = [(ForeignKey(entity = Event::class, parentColumns = ["id"], 20 | childColumns = ["event"], onDelete = CASCADE))]) 21 | data class SocialLink( 22 | @Id(IntegerIdHandler::class) 23 | @PrimaryKey 24 | val id: Int, 25 | val link: String, 26 | val name: String, 27 | @ColumnInfo(index = true) 28 | @Relationship("event") 29 | var event: EventId? = null 30 | ) 31 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/social/SocialLinkApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.social 2 | 3 | import io.reactivex.Flowable 4 | import retrofit2.http.GET 5 | import retrofit2.http.Path 6 | 7 | interface SocialLinkApi { 8 | 9 | @GET("events/{id}/social-links?include=event&fields[event]=id&page[size]=0") 10 | fun getSocialLinks(@Path("id") id: Long): Flowable> 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/social/SocialLinksDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.social 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import io.reactivex.Flowable 8 | 9 | @Dao 10 | interface SocialLinksDao { 11 | @Insert(onConflict = OnConflictStrategy.REPLACE) 12 | fun insertSocialLinks(socialLinks: List) 13 | 14 | @Query("DELETE FROM SocialLink") 15 | fun deleteAll() 16 | 17 | @Query("SELECT * from SocialLink WHERE event = :eventId") 18 | fun getAllSocialLinks(eventId: Long): Flowable> 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/social/SocialLinksRecyclerAdapter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.social 2 | 3 | import android.view.LayoutInflater 4 | import android.view.ViewGroup 5 | import androidx.recyclerview.widget.RecyclerView 6 | import java.util.ArrayList 7 | import org.fossasia.openevent.general.R 8 | 9 | class SocialLinksRecyclerAdapter : RecyclerView.Adapter() { 10 | 11 | private val socialLinks = ArrayList() 12 | 13 | fun addAll(socialLinkList: List) { 14 | if (socialLinkList.isNotEmpty()) 15 | this.socialLinks.clear() 16 | this.socialLinks.addAll(socialLinkList) 17 | notifyDataSetChanged() 18 | } 19 | 20 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SocialLinksViewHolder { 21 | val view = LayoutInflater.from(parent.context).inflate(R.layout.item_social_link, parent, false) 22 | return SocialLinksViewHolder(view, parent.context) 23 | } 24 | 25 | override fun onBindViewHolder(holder: SocialLinksViewHolder, position: Int) { 26 | val socialLink = socialLinks[position] 27 | holder.bind(socialLink) 28 | } 29 | 30 | override fun getItemCount(): Int { 31 | return socialLinks.size 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/social/SocialLinksService.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.social 2 | 3 | import io.reactivex.Flowable 4 | 5 | class SocialLinksService( 6 | private val socialLinkApi: SocialLinkApi, 7 | private val socialLinksDao: SocialLinksDao 8 | ) { 9 | 10 | fun getSocialLinks(id: Long): Flowable> { 11 | 12 | val socialFlowable = socialLinksDao.getAllSocialLinks(id) 13 | return socialFlowable.switchMap { 14 | if (it.isNotEmpty()) 15 | socialFlowable 16 | else 17 | socialLinkApi.getSocialLinks(id) 18 | .map { 19 | socialLinksDao.insertSocialLinks(it) 20 | } 21 | .flatMap { 22 | socialFlowable 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakercall/SpeakersCall.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakercall 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Type 10 | 11 | @Type("speakers-call") 12 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 13 | @Entity 14 | data class SpeakersCall( 15 | @Id(LongIdHandler::class) 16 | @PrimaryKey 17 | val id: Long, 18 | val announcement: String, 19 | val startsAt: String, 20 | val endsAt: String, 21 | val hash: String?, 22 | val privacy: String? 23 | ) 24 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakercall/SpeakersCallConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakercall 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | 7 | class SpeakersCallConverter { 8 | @TypeConverter 9 | fun toSpeakersCall(json: String): SpeakersCall? { 10 | return jacksonObjectMapper().readerFor(SpeakersCall::class.java).readValue(json) 11 | } 12 | 13 | @TypeConverter 14 | fun toJson(speakersCall: SpeakersCall?) = ObjectMapper().writeValueAsString(speakersCall) 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakercall/SpeakersCallDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakercall 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy.REPLACE 6 | import androidx.room.Query 7 | import io.reactivex.Single 8 | 9 | @Dao 10 | interface SpeakersCallDao { 11 | 12 | @Insert(onConflict = REPLACE) 13 | fun insertSpeakerCall(speakers: SpeakersCall) 14 | 15 | @Query("SELECT * from SpeakersCall WHERE id = :id") 16 | fun getSpeakerCall(id: Long): Single 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakercall/form/SessionIdentifier.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakercall.form 2 | 3 | object SessionIdentifier { 4 | val TITLE = "title" 5 | val SUBTITLE = "subtitle" 6 | val SHORT_ABSTRACT = "shortAbstract" 7 | val LONG_ABSTRACT = "longAbstract" 8 | val COMMENTS = "comments" 9 | val TRACK = "track" 10 | val SESSION_TYPE = "session_type" 11 | val LANGUAGE = "language" 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakercall/form/SpeakerIdentifier.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakercall.form 2 | 3 | object SpeakerIdentifier { 4 | val NAME = "name" 5 | val EMAIL = "email" 6 | val PHOTO = "photoUrl" 7 | val ORGANIZATION = "organisation" 8 | val POSITION = "position" 9 | val COUNTRY = "country" 10 | val SHORT_BIO = "shortBiography" 11 | val LONG_BIO = "longBiography" 12 | val MOBILE = "mobile" 13 | val WEBSITE = "website" 14 | val FACEBOOK = "facebook" 15 | val TWITTER = "twitter" 16 | val GITHUB = "github" 17 | val LINKEDIN = "linkedin" 18 | val SPEAKING_EXPERIENCE = "speakingExperience" 19 | val HEARD_FROM = "heardFrom" 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakers/ListSpeakerIdConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakers 2 | 3 | import androidx.room.TypeConverter 4 | import com.fasterxml.jackson.core.type.TypeReference 5 | import com.fasterxml.jackson.databind.ObjectMapper 6 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 7 | 8 | class ListSpeakerIdConverter { 9 | 10 | @TypeConverter 11 | fun fromListSpeakerId(speakerIdList: List): String { 12 | return ObjectMapper().writeValueAsString(speakerIdList) 13 | } 14 | 15 | @TypeConverter 16 | fun toListSpeakerId(speakerIdList: String): List { 17 | return jacksonObjectMapper().readValue(speakerIdList, object : TypeReference>() {}) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakers 2 | 3 | import io.reactivex.Single 4 | import org.fossasia.openevent.general.attendees.forms.CustomForm 5 | import retrofit2.http.Body 6 | import retrofit2.http.GET 7 | import retrofit2.http.PATCH 8 | import retrofit2.http.POST 9 | import retrofit2.http.Path 10 | import retrofit2.http.Query 11 | 12 | interface SpeakerApi { 13 | 14 | @GET("events/{id}/speakers") 15 | fun getSpeakerForEvent( 16 | @Path("id") id: Long, 17 | @Query("filter") filter: String 18 | ): Single> 19 | 20 | @GET("sessions/{sessionId}/speakers") 21 | fun getSpeakersForSession(@Path("sessionId") id: Long): Single> 22 | 23 | @GET("users/{user_id}/speakers?include=event,user") 24 | fun getSpeakerForUser( 25 | @Path("user_id") userId: Long, 26 | @Query("filter") query: String 27 | ): Single> 28 | 29 | @POST("speakers") 30 | fun addSpeaker(@Body speaker: Speaker): Single 31 | 32 | @PATCH("speakers/{speakerId}") 33 | fun updateSpeaker(@Path("speakerId") speakerId: Long, @Body speaker: Speaker): Single 34 | 35 | @GET("events/{id}/custom-forms") 36 | fun getCustomForms( 37 | @Path("id") eventId: Long, 38 | @Query("filter") filter: String 39 | ): Single> 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakers 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy.REPLACE 6 | import androidx.room.Query 7 | import io.reactivex.Flowable 8 | import io.reactivex.Single 9 | 10 | @Dao 11 | interface SpeakerDao { 12 | 13 | @Insert(onConflict = REPLACE) 14 | fun insertSpeakers(speakers: List) 15 | 16 | @Insert(onConflict = REPLACE) 17 | fun insertSpeaker(speaker: Speaker) 18 | 19 | @Query("SELECT * from Speaker WHERE id = :id") 20 | fun getSpeaker(id: Long): Flowable 21 | 22 | @Query("SELECT * FROM speaker WHERE email = :email AND event = :eventId") 23 | fun getSpeakerByEmailAndEvent(email: String, eventId: Long): Single 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerId.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakers 2 | 3 | import com.github.jasminb.jsonapi.LongIdHandler 4 | import com.github.jasminb.jsonapi.annotations.Id 5 | import com.github.jasminb.jsonapi.annotations.Type 6 | 7 | @Type("speaker") 8 | data class SpeakerId( 9 | @Id(LongIdHandler::class) 10 | val id: Long 11 | ) 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerWithEvent.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakers 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.Index 7 | import org.fossasia.openevent.general.event.Event 8 | 9 | @Entity( 10 | primaryKeys = ["event_id", "speaker_id"], 11 | indices = [ 12 | Index(value = ["event_id"]), 13 | Index(value = ["speaker_id"]) 14 | ], 15 | foreignKeys = [ 16 | ForeignKey(entity = Event::class, 17 | parentColumns = ["id"], 18 | childColumns = ["event_id"]), 19 | ForeignKey(entity = Speaker::class, 20 | parentColumns = ["id"], 21 | childColumns = ["speaker_id"]) 22 | ]) 23 | data class SpeakerWithEvent( 24 | @ColumnInfo(name = "event_id") val eventId: Long, 25 | @ColumnInfo(name = "speaker_id") val speakerId: Long 26 | ) 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerWithEventDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.speakers 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Insert 6 | import androidx.room.OnConflictStrategy 7 | import androidx.room.Query 8 | 9 | @Dao 10 | interface SpeakerWithEventDao { 11 | @Query(""" 12 | SELECT speaker.* FROM speaker 13 | INNER JOIN speakerwithevent ON 14 | speaker.id = speakerwithevent.speaker_id 15 | WHERE speakerwithevent.event_id = :eventID 16 | """) 17 | fun getSpeakerWithEventId(eventID: Long): LiveData> 18 | 19 | @Insert(onConflict = OnConflictStrategy.IGNORE) 20 | fun insert(join: SpeakerWithEvent) 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sponsor/Sponsor.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sponsor 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | import com.fasterxml.jackson.databind.PropertyNamingStrategy 6 | import com.fasterxml.jackson.databind.annotation.JsonNaming 7 | import com.github.jasminb.jsonapi.LongIdHandler 8 | import com.github.jasminb.jsonapi.annotations.Id 9 | import com.github.jasminb.jsonapi.annotations.Type 10 | 11 | @Type("sponsor") 12 | @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) 13 | @Entity 14 | data class Sponsor( 15 | @Id(LongIdHandler::class) 16 | @PrimaryKey 17 | val id: Long, 18 | val name: String?, 19 | val description: String?, 20 | val url: String?, 21 | val logoUrl: String?, 22 | val level: Int, 23 | val type: String? 24 | ) 25 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sponsor/SponsorApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sponsor 2 | 3 | import io.reactivex.Single 4 | import retrofit2.http.GET 5 | import retrofit2.http.Path 6 | 7 | interface SponsorApi { 8 | @GET("events/{id}/sponsors") 9 | fun getSponsorWithEvent(@Path("id") id: Long): Single> 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sponsor/SponsorDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sponsor 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy.REPLACE 6 | 7 | @Dao 8 | interface SponsorDao { 9 | 10 | @Insert(onConflict = REPLACE) 11 | fun insertSponsor(sponsor: Sponsor) 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sponsor/SponsorService.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sponsor 2 | 3 | import io.reactivex.Single 4 | 5 | class SponsorService( 6 | private val sponsorApi: SponsorApi, 7 | private val sponsorDao: SponsorDao, 8 | private val sponsorWithEventDao: SponsorWithEventDao 9 | ) { 10 | fun fetchSponsorsWithEvent(id: Long): Single> { 11 | return sponsorApi.getSponsorWithEvent(id).doOnSuccess { sponsors -> 12 | sponsors.forEach { sponsor -> 13 | sponsorDao.insertSponsor(sponsor) 14 | sponsorWithEventDao.insert(SponsorWithEvent(id, sponsor.id)) 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sponsor/SponsorUtil.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sponsor 2 | 3 | object SponsorUtil { 4 | fun sortSponsorByLevel(sponsors: List): List { 5 | return sponsors.sortedWith(compareBy(Sponsor::level)) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sponsor/SponsorWIthEvent.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sponsor 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.ForeignKey 6 | import androidx.room.Index 7 | import org.fossasia.openevent.general.event.Event 8 | 9 | @Entity( 10 | primaryKeys = ["event_id", "sponsor_id"], 11 | indices = [ 12 | Index(value = ["event_id"]), 13 | Index(value = ["sponsor_id"]) 14 | ], 15 | foreignKeys = [ 16 | ForeignKey(entity = Event::class, 17 | parentColumns = ["id"], 18 | childColumns = ["event_id"]), 19 | ForeignKey(entity = Sponsor::class, 20 | parentColumns = ["id"], 21 | childColumns = ["sponsor_id"]) 22 | ]) 23 | data class SponsorWithEvent( 24 | @ColumnInfo(name = "event_id") val eventId: Long, 25 | @ColumnInfo(name = "sponsor_id") val sponsorId: Long 26 | ) 27 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/sponsor/SponsorWithEventDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.sponsor 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Insert 6 | import androidx.room.OnConflictStrategy 7 | import androidx.room.Query 8 | 9 | @Dao 10 | interface SponsorWithEventDao { 11 | @Query(""" 12 | SELECT sponsor.* FROM sponsor 13 | INNER JOIN sponsorwithevent ON 14 | sponsor_id = sponsorwithevent.sponsor_id 15 | WHERE sponsorwithevent.event_id = :eventID 16 | """) 17 | fun getSponsorWithEventId(eventID: Long): LiveData> 18 | 19 | @Insert(onConflict = OnConflictStrategy.IGNORE) 20 | fun insert(join: SponsorWithEvent) 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/ticket/TicketApi.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.ticket 2 | 3 | import io.reactivex.Flowable 4 | import retrofit2.http.GET 5 | import retrofit2.http.Path 6 | 7 | interface TicketApi { 8 | 9 | @GET("events/{id}/tickets?include=event&fields[event]=id&page[size]=0") 10 | fun getTickets(@Path("id") id: Long): Flowable> 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/ticket/TicketDao.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.ticket 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import io.reactivex.Flowable 8 | import io.reactivex.Single 9 | 10 | @Dao 11 | interface TicketDao { 12 | @Insert(onConflict = OnConflictStrategy.REPLACE) 13 | fun insertTickets(tickets: List) 14 | 15 | @Query("DELETE FROM Ticket") 16 | fun deleteAll() 17 | 18 | @Query("SELECT * from Ticket WHERE event = :eventId") 19 | fun getTicketsForEvent(eventId: Long): Flowable> 20 | 21 | @Query("SELECT * from Ticket WHERE id = :id") 22 | fun getTicketDetails(id: Long): Single 23 | 24 | @Query("SELECT * from Ticket WHERE id in (:ids)") 25 | fun getTicketsWithIds(ids: List): Single> 26 | 27 | @Query("SELECT MAX(price) as maxValue, MIN(price) as minValue from Ticket WHERE event = :eventId") 28 | fun getTicketPriceRange(eventId: Long): Single 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/ticket/TicketId.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.ticket 2 | 3 | import com.github.jasminb.jsonapi.LongIdHandler 4 | import com.github.jasminb.jsonapi.annotations.Id 5 | import com.github.jasminb.jsonapi.annotations.Type 6 | 7 | @Type("ticket") 8 | data class TicketId( 9 | @Id(LongIdHandler::class) 10 | val id: Long 11 | ) 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/ticket/TicketIdAndQtyWrapper.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.ticket 2 | 3 | import java.io.Serializable 4 | 5 | /** 6 | * A wrapper class around a list of Ticket Ids and Quantities. 7 | * This class allows for passing this data between frgments in a typesafe manner. 8 | * 9 | * @param value The list of ids and quantities 10 | */ 11 | data class TicketIdAndQtyWrapper(val value: List>) : Serializable 12 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/ticket/TicketIdConverter.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.ticket 2 | 3 | import androidx.room.TypeConverter 4 | 5 | class TicketIdConverter { 6 | 7 | @TypeConverter 8 | fun fromTicketId(ticketId: TicketId?): Long? { 9 | return ticketId?.id 10 | } 11 | 12 | @TypeConverter 13 | fun toTicketId(id: Long?): TicketId? { 14 | return id?.let { 15 | TicketId(id) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/ticket/TicketPriceRange.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.ticket 2 | 3 | data class TicketPriceRange( 4 | val maxValue: Float, 5 | val minValue: Float 6 | ) 7 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/utils/AppLinkData.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.utils 2 | 3 | data class AppLinkData( 4 | val destinationId: Int, 5 | val argumentKey: String, 6 | val argumentValue: String 7 | ) 8 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/utils/Error.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.utils 2 | 3 | import org.fossasia.openevent.general.utils.StringUtils.isEmpty 4 | 5 | class Error { 6 | 7 | var title: String? = null 8 | var detail: String? = null 9 | var pointer: String? = null 10 | var code: String? = null 11 | 12 | override fun toString(): String { 13 | 14 | if (isEmpty(title)) { 15 | if (!isEmpty(detail)) { 16 | return (if (isEmpty(pointer)) { 17 | detail 18 | } else { 19 | "$detail - $pointer" 20 | }).toString() 21 | } 22 | } else { 23 | return if (isEmpty(pointer)) { 24 | "$title: $detail" 25 | } else { 26 | "$title: $detail - $pointer" 27 | } 28 | } 29 | 30 | return "" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/utils/HttpErrors.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.utils 2 | 3 | object HttpErrors { 4 | const val CONFLICT = 409 5 | const val UNAUTHORIZED = 401 6 | const val NOT_FOUND = 404 7 | const val BAD_REQUEST = 400 8 | const val FORBIDDEN = 403 9 | const val METHOD_NOT_ALLOWED = 405 10 | const val REQUEST_TIMEOUT = 408 11 | const val UNPROCESSABLE_ENTITY = 422 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/utils/ImageUtils.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.utils 2 | 3 | import android.graphics.Bitmap 4 | import android.graphics.BitmapFactory 5 | import android.util.Base64 6 | import java.io.ByteArrayOutputStream 7 | 8 | object ImageUtils { 9 | 10 | fun encodeBitmap(bitmap: Bitmap): String { 11 | val byteArrayOutputStream = ByteArrayOutputStream() 12 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream) 13 | val byteArray = byteArrayOutputStream.toByteArray() 14 | return Base64.encodeToString(byteArray, Base64.DEFAULT) 15 | } 16 | 17 | fun decodeBitmap(encodedBitmap: String): Bitmap { 18 | val decodedString = Base64.decode(encodedBitmap, Base64.DEFAULT) 19 | return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/utils/extensions/FragmentExt.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.utils.extensions 2 | 3 | import android.os.Build 4 | import androidx.fragment.app.Fragment 5 | import androidx.transition.TransitionInflater 6 | 7 | const val SUPPORTED_TRANSITION_VERSION = Build.VERSION_CODES.O 8 | 9 | fun Fragment.setStartPostponedEnterTransition() { 10 | if (Build.VERSION.SDK_INT >= SUPPORTED_TRANSITION_VERSION) { 11 | this.startPostponedEnterTransition() 12 | } 13 | } 14 | 15 | fun Fragment.setSharedElementEnterTransition(transition: Int = android.R.transition.move) { 16 | if (Build.VERSION.SDK_INT >= SUPPORTED_TRANSITION_VERSION) { 17 | sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(transition) 18 | } 19 | } 20 | 21 | fun Fragment.setPostponeSharedElementTransition() { 22 | if (Build.VERSION.SDK_INT >= SUPPORTED_TRANSITION_VERSION) { 23 | postponeEnterTransition() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/utils/extensions/LiveDataExtensions.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.utils.extensions 2 | 3 | import androidx.lifecycle.LifecycleOwner 4 | import androidx.lifecycle.LiveData 5 | import androidx.lifecycle.MediatorLiveData 6 | import androidx.lifecycle.Observer 7 | import org.fossasia.openevent.general.common.SingleLiveEvent 8 | 9 | class NonNullMediatorLiveData : MediatorLiveData() 10 | 11 | fun LiveData.nonNull(): NonNullMediatorLiveData { 12 | val mediator: NonNullMediatorLiveData = NonNullMediatorLiveData() 13 | mediator.addSource(this) { nullable -> nullable?.let { mediator.value = it } } 14 | return mediator 15 | } 16 | 17 | fun SingleLiveEvent.nonNull(): SingleLiveEvent = this 18 | 19 | fun NonNullMediatorLiveData.observe(owner: LifecycleOwner, observer: (t: T) -> Unit) { 20 | this.observe(owner, Observer { 21 | it?.let(observer) 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/utils/extensions/RxExtensions.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.utils.extensions 2 | 3 | import io.reactivex.Completable 4 | import io.reactivex.Flowable 5 | import io.reactivex.Single 6 | import io.reactivex.android.schedulers.AndroidSchedulers 7 | import io.reactivex.schedulers.Schedulers 8 | 9 | fun Single.withDefaultSchedulers(): 10 | Single = subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) 11 | 12 | fun Flowable.withDefaultSchedulers(): 13 | Flowable = subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) 14 | 15 | fun Completable.withDefaultSchedulers(): 16 | Completable = subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) 17 | -------------------------------------------------------------------------------- /app/src/main/java/org/fossasia/openevent/general/utils/extensions/ViewExt.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.utils.extensions 2 | 3 | import android.animation.Animator 4 | import android.animation.AnimatorListenerAdapter 5 | import android.view.View 6 | import androidx.core.view.isVisible 7 | 8 | fun View.hideWithFading(duration: Long = 200L) { 9 | alpha = 1f 10 | animate().alpha(0f) 11 | .setDuration(duration) 12 | .setListener(object : AnimatorListenerAdapter() { 13 | override fun onAnimationEnd(animation: Animator?, isReverse: Boolean) { 14 | isVisible = false 15 | } 16 | override fun onAnimationCancel(animation: Animator?) { 17 | isVisible = false 18 | } 19 | }) 20 | } 21 | 22 | fun View.showWithFading(duration: Long = 200L) { 23 | alpha = 0f 24 | isVisible = true 25 | animate().alpha(1f).duration = duration 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/res/anim/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_down.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_up.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/color/navigation_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/color/text_color_chip_state_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_fragment.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/border.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/border_background_ticket_timer.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/border_curved.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/border_order_status.xml: -------------------------------------------------------------------------------- 1 | 3 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/circle_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/curved_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/filled_border.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/foreground_black_blur.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/drawable/header.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_account_circle_grey.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_back_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_back_white_cct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/drawable/ic_arrow_back_white_cct.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_arrow_forward.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_calendar.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_event.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_event_grey.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_favorite.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_favorite_border.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_favorite_border_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_favorite_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_refund.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_tick.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_ticket.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bio.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_blogger.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_checked.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_circle.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_clear.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_crop.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_edit.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_email.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_email_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_exit_to_app_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand_icon.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_facebook.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_flickr.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_github.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_google_plus.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_image.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_language_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_link_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_linkedin.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_location_on_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_location_pin.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_lock_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_mail_outline_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_map_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_no_internet.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_none.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_white.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_open_event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/drawable/ic_open_event.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_outline_account_circle.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_outline_ticket.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_person.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_person_add.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_person_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_grey.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_white.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share_grey.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_star_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tick_inside_circle.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_time.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_track.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twitter.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_website.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_wikipedia.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_youtube.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_image.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/scrim_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/splash_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/drawable/splash_logo.png -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_api_configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_confirm_delete_account.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 12 | 18 | 19 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/event_type_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_order_details.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_sponsors.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_enlarged_qr.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_faq.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_feedback.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 19 | 20 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_location_text.xml: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_social_link.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/placeholder_item_event_location.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 19 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/placeholder_item_event_type.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 16 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/menu/navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 14 | 18 | 19 | 23 | 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/menu/order_completed.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/menu/order_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 580dp 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-land/integers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-land/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Where do you go out? 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-sw600dp-land/integers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-sw600dp/integers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @string/today 5 | @string/tomorrow 6 | @string/weekend 7 | @string/month 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #673AB7 4 | #512DA8 5 | #03A9F4 6 | #000000 7 | #ffffff 8 | #ece9e9 9 | #918e8e 10 | #b498d1 11 | #333333 12 | #545454 13 | #dddddd 14 | #ffffaa 15 | #e20404 16 | 17 | #311B92 18 | #03A9F4 19 | #01579B 20 | 21 | #2889D2 22 | #21BA45 23 | #F2711C 24 | #b2b2b2 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/values/integers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/xml/file_provider.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/playStore/java/org/fossasia/openevent/general/auth/SmartAuthUtil.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general.auth 2 | 3 | import android.app.Activity 4 | import android.content.Intent 5 | import com.google.android.gms.auth.api.credentials.Credential 6 | import com.google.android.gms.auth.api.credentials.Credentials 7 | import com.google.android.gms.auth.api.credentials.CredentialsClient 8 | import com.google.android.gms.common.api.ResolvableApiException 9 | 10 | object SmartAuthUtil { 11 | fun getCredentialsClient(activity: Activity): CredentialsClient { 12 | return Credentials.getClient(activity) 13 | } 14 | 15 | fun handleResolvableApiException(rae: ResolvableApiException, activity: Activity, value: Int) { 16 | rae.startResolutionForResult(activity, value) 17 | } 18 | 19 | fun getEmailAddressFromIntent(data: Intent?): String? { 20 | return data?.getParcelableExtra(Credential.EXTRA_KEY)?.id 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/test/java/org/fossasia/openevent/general/DependencyTest.kt: -------------------------------------------------------------------------------- 1 | package org.fossasia.openevent.general 2 | 3 | import android.app.Application 4 | import org.fossasia.openevent.general.di.apiModule 5 | import org.fossasia.openevent.general.di.commonModule 6 | import org.fossasia.openevent.general.di.databaseModule 7 | import org.fossasia.openevent.general.di.networkModule 8 | import org.fossasia.openevent.general.di.viewModelModule 9 | import org.junit.Test 10 | import org.koin.android.ext.koin.androidContext 11 | import org.koin.dsl.koinApplication 12 | import org.koin.test.KoinTest 13 | import org.koin.test.check.checkModules 14 | import org.mockito.Mockito.mock 15 | 16 | class DependencyTest : KoinTest { 17 | @Test 18 | fun testDependencies() { 19 | koinApplication { 20 | androidContext(mock(Application::class.java)) 21 | modules(listOf(commonModule, apiModule, databaseModule, networkModule, viewModelModule)) 22 | }.checkModules() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext.kotlin_version = '1.4.10' 5 | 6 | repositories { 7 | google() 8 | mavenCentral() 9 | jcenter() 10 | maven { 11 | url "https://plugins.gradle.org/m2/" 12 | } 13 | } 14 | dependencies { 15 | classpath 'com.android.tools.build:gradle:8.0.0' 16 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 17 | classpath 'android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0' 18 | classpath "gradle.plugin.com.github.b3er.local.properties:local-properties-plugin:1.1" 19 | 20 | // NOTE: Do not place your application dependencies here; they belong 21 | // in the individual module build.gradle files 22 | } 23 | } 24 | 25 | allprojects { 26 | repositories { 27 | google() 28 | maven { url 'https://jitpack.io' } 29 | mavenCentral() 30 | jcenter() 31 | } 32 | ext { 33 | KEYSTORE_FILE = rootProject.file('scripts/key.jks') 34 | TRAVIS_BUILD = System.getenv("TRAVIS") == "true" && KEYSTORE_FILE.exists() 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /docs/images/ic_fdroid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/docs/images/ic_fdroid.png -------------------------------------------------------------------------------- /docs/images/ic_play_store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/docs/images/ic_play_store.png -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | json_key_file("./scripts/fastlane.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one 2 | package_name("com.eventyay.attendee") # e.g. com.krausefx.app 3 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:android) 17 | 18 | platform :android do 19 | desc "Runs all the tests" 20 | lane :test do 21 | gradle(task: "test") 22 | end 23 | 24 | desc "Submit a new Beta Build to Crashlytics Beta" 25 | lane :beta do 26 | gradle(task: "clean assembleRelease") 27 | crashlytics 28 | 29 | # sh "your_script.sh" 30 | # You can also use other beta testing services here 31 | end 32 | 33 | desc "Deploy a new version to the Google Play" 34 | lane :deploy do 35 | gradle(task: "clean assembleRelease") 36 | upload_to_play_store 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/10.txt: -------------------------------------------------------------------------------- 1 | - Speakers, Sessions, Sponsors and Tracks for an Event 2 | - See Notifications about Events and Orders 3 | - Submit feedbacks on events 4 | - Several other enhancements and bug fixes -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11.txt: -------------------------------------------------------------------------------- 1 | Several enhancements and bug fixes -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12.txt: -------------------------------------------------------------------------------- 1 | 🚀 Features and Enhancements 2 | 3 | - Update tickets section and display ticket status 4 | - Add donation tickets 5 | - Verify email and reset password with the app 6 | - Edit profile image 7 | - Improve filtering and sorting 8 | - Add pagination in different sections 9 | - Several UI enhancement 10 | 11 | 🐛 Bug Fixes 12 | 13 | - Multiple crashes 14 | - Fixes for API < 24 15 | - Error handling 16 | - Billing information for paid tickets 17 | - Event's time and timezone 18 | 19 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13.txt: -------------------------------------------------------------------------------- 1 | **v0.6.1:** 2 | HOTFIX: Fix search filter crashing 3 | 4 | **v0.6.0:** 5 | 🚀 Features and Enhancements 6 | 7 | - Update tickets section and display ticket status 8 | - Add donation tickets 9 | - Verify email and reset password with the app 10 | - Edit profile image 11 | - Improve filtering and sorting 12 | - Add pagination in different sections 13 | - Several UI enhancement 14 | 15 | 🐛 Bug Fixes 16 | 17 | - Multiple crashes 18 | - Fixes for API < 24 19 | - Error handling 20 | - Billing information for paid tickets 21 | - Event's time and timezone 22 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14.txt: -------------------------------------------------------------------------------- 1 | **v0.7.0:** 2 | 🚀 Features and Enhancements 3 | 4 | - Handle external ticket URL 5 | - Add tax information for tickets 6 | - Add autolink 7 | - Custom form for speakers and sessions 8 | - Improve animations 9 | 10 | 🐛 Bug Fixes 11 | 12 | - Event's timezone for sessions 13 | - Improve error handling for stripe and orders 14 | - Donation tickets 15 | - Multiple crashes 16 | - Date format 17 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15.txt: -------------------------------------------------------------------------------- 1 | **v0.8.0:** 2 | 🚀 Features and Enhancements 3 | 4 | - Enable PayPal payment option 5 | - Add order status information 6 | 7 | 🐛 Bug Fixes 8 | 9 | - Fix app link intent issue 10 | - Fix favorite events 11 | - Fix verification status for free tickets 12 | - Some UI fixes 13 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/16.txt: -------------------------------------------------------------------------------- 1 | v0.9.0: 2 | 🚀 Features 3 | 4 | - Reduce APK size by removing redundant Paypal binaries 5 | - Enable PayPal payment option 6 | 7 | 🐛 Bug Fixes 8 | 9 | - Fix app crash in search 10 | - Some UI fixes 11 | - Other fixes and dependency updates 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/17.txt: -------------------------------------------------------------------------------- 1 | v0.9.1: 2 | 3 | - Fix app crash on startup/login 4 | 5 | 🚀 Features 6 | 7 | - Reduce APK size by removing redundant Paypal binaries 8 | - Enable PayPal payment option 9 | 10 | 🐛 Bug Fixes 11 | 12 | - Fix app crash in search 13 | - Some UI fixes 14 | - Other fixes and dependency updates 15 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/6.txt: -------------------------------------------------------------------------------- 1 | Fix database migration issue -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/7.txt: -------------------------------------------------------------------------------- 1 | 🚀 Features 2 | 3 | - Sort tickets and grey out old tickets 4 | - add chips for search (#1518) 5 | - add event types for search 6 | - add Event Location 7 | - add Event Types Chips 8 | - Add option to change password 9 | - Add log out dialog in settings fragment 10 | - reimplement google smart lock for login 11 | 12 | 🐛 Bug Fixes -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/9.txt: -------------------------------------------------------------------------------- 1 | - Speakers, Sessions, Sponsors and Tracks for an Event 2 | - See Notifications about Events and Orders 3 | - Submit feedbacks on events 4 | - Several other enhancements and bug fixes -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | With EventYay Attendee, you can browse through different events happening nearby or anywhere in the world. You can get detailed information about the events and buy tickets. The app also offers other features such as displaying ticket details and easy check-in using QR code. If that’s not enough, the app also allows you to favorite events and search events by their name. 2 | 3 | Eventyay Attendee App provides following features for users: 4 | - All events by the organizers can be viewed 5 | - Functionality to filter out events by date, time, location and event name 6 | - Users can buy tickets and register as attendees for any event 7 | - Pay for their orders via PayPal and Stripe 8 | - All important event details such as location, date, and timing of the event can be viewed 9 | - Users can view all the tickets bought for an event with their status 10 | - Easy check-in using QR code for Tickets and see check-in timings 11 | - Users can view similar events 12 | - Users have the privilege to mark an event as favorite 13 | 14 | This app is proudly developed with the FOSSASIA community. 15 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_1.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_2.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_3.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_4.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_5.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_6.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_8.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot_9.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | Discover events listed on Eventyay.com from all over the world 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | Eventyay Attendee App -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/video.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/fastlane/metadata/android/en-US/video.txt -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | android.enableJetifier=true 13 | android.useAndroidX=true 14 | org.gradle.jvmargs=-Xmx1536m 15 | 16 | # When configured, Gradle will run in incubating parallel mode. 17 | # This option should only be used with decoupled projects. More details, visit 18 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 19 | # org.gradle.parallel=true 20 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon May 11 23:14:47 IST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip 7 | -------------------------------------------------------------------------------- /scripts/prep-key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | [[ $TRAVIS_REPO_SLUG =~ ^(fossasia/open-event-attendee-android)$ ]] && IS_FOSS_SLUG=true || IS_FOSS_SLUG=false 5 | [[ $TRAVIS_PULL_REQUEST_SLUG =~ ^(fossasia/open-event-attendee-android)$ ]] && IS_FOSS_PR=true || IS_FOSS_PR=false 6 | [[ $TRAVIS_BRANCH =~ ^(development|master)$ && $IS_FOSS_SLUG ]] && BRANCH_DEPLOYORDEV=true || BRANCH_DEPLOYORDEV=false 7 | 8 | [[ $TRAVIS_BRANCH =~ ^(master)$ && $IS_FOSS_SLUG ]] && IS_PUBLISH_BRANCH=true || IS_PUBLISH_BRANCH=false 9 | 10 | [[ $TRAVIS_PULL_REQUEST =~ ^(false)$ && $BRANCH_DEPLOYORDEV ]] && export DEV_OR_MASTER_BUILD=${DEV_OR_MASTER_BUILD:-true} || export DEV_OR_MASTER_BUILD=${DEV_OR_MASTER_BUILD:-false} 11 | 12 | [[ $IS_PUBLISH_BRANCH && $IS_FOSS_PR =~ ^(true)$ ]] && export PR_FOR_RELEASE=${PR_FOR_RELEASE:-true} || export PR_FOR_RELEASE=${PR_FOR_RELEASE:-false} 13 | 14 | if ! ( $DEV_OR_MASTER_BUILD || $PR_FOR_RELEASE ); then 15 | echo "We decrypt key only for pushes to the master branch and not PRs. So, skip." 16 | exit 0 17 | fi 18 | 19 | # Decrypt keys 20 | openssl aes-256-cbc -K $encrypted_59a1db41ee4d_key -iv $encrypted_59a1db41ee4d_iv -in ./scripts/secrets.tar.enc -out ./scripts/secrets.tar -d 21 | tar xvf ./scripts/secrets.tar -C scripts/ 22 | -------------------------------------------------------------------------------- /scripts/secrets.tar.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fossasia/open-event-attendee-android/9e3afa05753332f9ca3edebb118bae9d7b224554/scripts/secrets.tar.enc -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------