├── .github
├── CONTRIBUTING.md
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── deploy_beta.yml
│ ├── deploy_web.yml
│ └── lint_test_build.yml
├── .gitignore
├── .metadata
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── SECURITY.md
├── analysis_options.yaml
├── android
├── .gitignore
├── Gemfile
├── app
│ ├── build.gradle
│ ├── google-services.json
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── de
│ │ │ │ └── tum
│ │ │ │ └── in
│ │ │ │ └── tumcampus
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── util
│ │ │ │ ├── ColorExtension.kt
│ │ │ │ ├── Const.kt
│ │ │ │ ├── DateTimeSerializer.kt
│ │ │ │ └── DateTimeUtils.kt
│ │ │ │ └── widgets
│ │ │ │ └── calendar
│ │ │ │ ├── CalendarWidgetProvider.kt
│ │ │ │ ├── CalendarWidgetService.kt
│ │ │ │ └── WidgetCalendarItem.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ ├── appwidget_preview.png
│ │ │ ├── launch_background.xml
│ │ │ └── rounded_background.xml
│ │ │ ├── layout
│ │ │ ├── calendar_widget.xml
│ │ │ └── calendar_widget_item.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ └── ic_launcher.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── values-de
│ │ │ └── strings.xml
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ ├── values-v31
│ │ │ └── themes.xml
│ │ │ ├── values
│ │ │ ├── attrs.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ ├── styles.xml
│ │ │ └── themes.xml
│ │ │ ├── xml-v31
│ │ │ └── calendar_widget_info.xml
│ │ │ └── xml
│ │ │ └── calendar_widget_info.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── build
│ └── .last_build_id
├── fastlane
│ ├── Appfile
│ └── Fastfile
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── images
│ ├── campus
│ │ ├── campus-freising.jpg
│ │ ├── campus-garching.jpeg
│ │ ├── campus-klinikum.jpg
│ │ ├── campus-olympia.jpg
│ │ └── campus-stamm.jpeg
│ ├── errors
│ │ └── error.svg
│ ├── location.png
│ ├── logos
│ │ ├── tum-logo-blue-text.png
│ │ ├── tum-logo-blue.png
│ │ ├── tum-logo-rainbow.png
│ │ └── tum-logo-white.png
│ ├── placeholders
│ │ ├── movie_placeholder.png
│ │ ├── news_placeholder.png
│ │ ├── portrait_placeholder.png
│ │ └── student_club_placeholder.png
│ └── tower.png
├── lottieFiles
│ ├── gradient_background_blue_red.json
│ ├── gradient_background_blue_white.json
│ ├── gradient_background_blue_white_speedup.json
│ └── gradient_background_silver_white.json
├── mapStyles
│ ├── darkMapTheme.json
│ └── lightMapTheme.json
├── translations
│ ├── de.json
│ └── en.json
└── videos
│ └── token-tutorial.mp4
├── devtools_options.yaml
├── ios
├── .gitignore
├── CalendarWidget
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x-1.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x-1.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x-1.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ ├── ItunesArtwork@2x.png
│ │ │ ├── slice1@3x copy 2.png
│ │ │ ├── slice1@3x copy 3-1.png
│ │ │ ├── slice1@3x copy 3.png
│ │ │ ├── slice1@3x copy 4.png
│ │ │ ├── slice1@3x copy 5.png
│ │ │ ├── slice1@3x copy 6-1.png
│ │ │ ├── slice1@3x copy 6.png
│ │ │ ├── slice1@3x copy 7-1.png
│ │ │ ├── slice1@3x copy 7.png
│ │ │ └── slice1@3x copy 8.png
│ │ ├── Contents.json
│ │ └── WidgetBackground.colorset
│ │ │ └── Contents.json
│ ├── CalendarEntry.swift
│ ├── CalendarEventType.swift
│ ├── CalendarEventView.swift
│ ├── CalendarWidget.swift
│ ├── CalendarWidgetBundle.swift
│ ├── CalendarWidgetContent.swift
│ ├── CalendarWidgetEntry.swift
│ ├── ColorExtension.swift
│ ├── DateExtension.swift
│ └── Info.plist
├── CalendarWidgetExtension.entitlements
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Gemfile
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x-1.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x-1.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x-1.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ ├── ItunesArtwork@2x.png
│ │ │ ├── slice1@3x copy 2.png
│ │ │ ├── slice1@3x copy 3-1.png
│ │ │ ├── slice1@3x copy 3.png
│ │ │ ├── slice1@3x copy 4.png
│ │ │ ├── slice1@3x copy 5.png
│ │ │ ├── slice1@3x copy 6-1.png
│ │ │ ├── slice1@3x copy 6.png
│ │ │ ├── slice1@3x copy 7-1.png
│ │ │ ├── slice1@3x copy 7.png
│ │ │ └── slice1@3x copy 8.png
│ │ ├── Contents.json
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── README.md
│ │ │ └── logo-white.png
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── GoogleService-Info.plist
│ ├── Info.plist
│ ├── Localizable.xcstrings
│ ├── Runner-Bridging-Header.h
│ └── Runner.entitlements
├── build
│ └── .last_build_id
├── ci_scripts
│ └── ci_post_clone.sh
├── fastlane
│ ├── Appfile
│ ├── Fastfile
│ └── Matchfile
└── firebase_app_id_file.json
├── lib
├── base
│ ├── enums
│ │ ├── appearance.dart
│ │ ├── campus.dart
│ │ ├── credentials.dart
│ │ ├── device.dart
│ │ ├── error_handling_view_type.dart
│ │ ├── gender.dart
│ │ ├── home_widget.dart
│ │ ├── remote_config_message.dart
│ │ ├── role.dart
│ │ ├── search_category.dart
│ │ ├── search_type.dart
│ │ ├── shortcut_item.dart
│ │ ├── user_preference.dart
│ │ └── widget_type.dart
│ ├── errorHandling
│ │ ├── default_error_router.dart
│ │ ├── dio_exception_router.dart
│ │ ├── error_handling_router.dart
│ │ ├── error_handling_view.dart
│ │ ├── grpc_error_router.dart
│ │ ├── search_exception_router.dart
│ │ ├── tum_online_api_exception_router.dart
│ │ └── type_error_router.dart
│ ├── extensions
│ │ ├── base_64_decode_image_data.dart
│ │ ├── cast.dart
│ │ ├── color.dart
│ │ ├── context.dart
│ │ ├── date_time.dart
│ │ ├── latlng_to_json.dart
│ │ ├── locale_fullname.dart
│ │ ├── string_capitalize.dart
│ │ ├── string_levenshtein.dart
│ │ ├── string_remove_diacritics.dart
│ │ └── string_valid_chars.dart
│ ├── networking
│ │ ├── apis
│ │ │ ├── eatApi
│ │ │ │ ├── eat_api.dart
│ │ │ │ └── eat_api_endpoint.dart
│ │ │ ├── google
│ │ │ │ └── protobuf
│ │ │ │ │ ├── empty.pb.dart
│ │ │ │ │ ├── empty.pbenum.dart
│ │ │ │ │ ├── empty.pbjson.dart
│ │ │ │ │ ├── timestamp.pb.dart
│ │ │ │ │ ├── timestamp.pbenum.dart
│ │ │ │ │ └── timestamp.pbjson.dart
│ │ │ ├── irisApi
│ │ │ │ ├── iris_api.dart
│ │ │ │ └── iris_api_endpoint.dart
│ │ │ ├── mvvDeparturesApi
│ │ │ │ └── mvv_departures_api.dart
│ │ │ ├── navigaTumApi
│ │ │ │ ├── navigatum_api.dart
│ │ │ │ └── navigatum_api_endpoint.dart
│ │ │ ├── tumOnlineApi
│ │ │ │ ├── tum_online_api.dart
│ │ │ │ ├── tum_online_api_endpoint.dart
│ │ │ │ └── tum_online_api_exception.dart
│ │ │ └── tumdev
│ │ │ │ ├── campus_backend.pb.dart
│ │ │ │ ├── campus_backend.pbenum.dart
│ │ │ │ ├── campus_backend.pbgrpc.dart
│ │ │ │ └── campus_backend.pbjson.dart
│ │ ├── base
│ │ │ ├── api_response.dart
│ │ │ ├── grpc_client.dart
│ │ │ └── rest_client.dart
│ │ ├── cache
│ │ │ ├── cache.dart
│ │ │ ├── cache_entry.dart
│ │ │ ├── cache_entry.g.dart
│ │ │ ├── grpc_cache_interceptor.dart
│ │ │ └── rest_cache_interceptor.dart
│ │ └── protocols
│ │ │ ├── api.dart
│ │ │ ├── api_exception.dart
│ │ │ └── api_exception.g.dart
│ ├── routing
│ │ ├── router.dart
│ │ ├── router_service.dart
│ │ └── routes.dart
│ ├── services
│ │ ├── connection_service.dart
│ │ ├── device_type_service.dart
│ │ ├── location_service.dart
│ │ └── user_preferences_service.dart
│ ├── theme
│ │ ├── constants.dart
│ │ ├── dark_theme.dart
│ │ └── light_theme.dart
│ └── util
│ │ ├── card_with_padding.dart
│ │ ├── color_picker_view.dart
│ │ ├── custom_back_button.dart
│ │ ├── days_parser.dart
│ │ ├── delayed_loading_indicator.dart
│ │ ├── diagonalStripePattern
│ │ ├── diagonal_stripe_pattern_view.dart
│ │ └── stripe_pattern_painter.dart
│ │ ├── enum_parser.dart
│ │ ├── fast_hash.dart
│ │ ├── fullscreen_image_view.dart
│ │ ├── grid_utility.dart
│ │ ├── horizontal_slider.dart
│ │ ├── hyperlink_text.dart
│ │ ├── icon_text.dart
│ │ ├── info_row.dart
│ │ ├── last_updated_text.dart
│ │ ├── map_launcher.dart
│ │ ├── padded_divider.dart
│ │ ├── placeholder_text.dart
│ │ ├── places_util.dart
│ │ ├── read_list_value.dart
│ │ ├── semester_calculator.dart
│ │ ├── seperated_list.dart
│ │ ├── shimmer_view.dart
│ │ ├── speaker.dart
│ │ ├── string_parser.dart
│ │ └── url_launcher.dart
├── calendarComponent
│ ├── model
│ │ ├── calendar_data_source.dart
│ │ ├── calendar_editing.dart
│ │ ├── calendar_editing.g.dart
│ │ ├── calendar_event.dart
│ │ ├── calendar_event.g.dart
│ │ ├── calendar_preferences.dart
│ │ └── calendar_preferences.g.dart
│ ├── services
│ │ ├── calendar_preference_service.dart
│ │ ├── calendar_service.dart
│ │ └── calendar_view_service.dart
│ ├── viewModels
│ │ ├── calendar_addition_viewmodel.dart
│ │ └── calendar_viewmodel.dart
│ └── views
│ │ ├── calendar_day_view.dart
│ │ ├── calendar_event_view.dart
│ │ ├── calendar_month_view.dart
│ │ ├── calendar_week_view.dart
│ │ ├── calendars_view.dart
│ │ ├── custom_event_view.dart
│ │ ├── event_creation_date_time_picker.dart
│ │ ├── event_creation_form_field.dart
│ │ ├── event_creation_view.dart
│ │ ├── homeWidget
│ │ ├── calendar_widget_event_view.dart
│ │ └── calendar_widget_view.dart
│ │ └── visibility_button_view.dart
├── campusComponent
│ ├── model
│ │ ├── student_club.dart
│ │ └── student_club_collection.dart
│ ├── screen
│ │ ├── campus_screen.dart
│ │ ├── movie_screen.dart
│ │ ├── news_screen.dart
│ │ └── student_clubs_screen.dart
│ ├── service
│ │ ├── movie_service.dart
│ │ ├── news_service.dart
│ │ └── student_club_service.dart
│ ├── view
│ │ ├── movie
│ │ │ ├── movie_card_view.dart
│ │ │ ├── movie_grid_view.dart
│ │ │ └── movies_widget_view.dart
│ │ ├── news
│ │ │ ├── news_card_view.dart
│ │ │ └── news_widget_view.dart
│ │ └── studentClub
│ │ │ ├── student_club_card_view.dart
│ │ │ ├── student_club_grid_view.dart
│ │ │ └── student_club_widget_view.dart
│ └── viewmodel
│ │ ├── movies_viewmodel.dart
│ │ ├── news_viewmodel.dart
│ │ └── student_club_viewmodel.dart
├── feedbackComponent
│ ├── services
│ │ └── feedback_service.dart
│ ├── viewModels
│ │ └── feedback_viewmodel.dart
│ └── views
│ │ ├── feedback_checkmark_view.dart
│ │ ├── feedback_form_view.dart
│ │ ├── feedback_success_view.dart
│ │ └── feedback_textfield.dart
├── firebase_options.dart
├── homeComponent
│ ├── model
│ │ ├── departure.dart
│ │ ├── departure.g.dart
│ │ ├── departures_preference.dart
│ │ ├── departures_preference.g.dart
│ │ ├── mvv_response.dart
│ │ ├── mvv_response.g.dart
│ │ ├── station.dart
│ │ └── station.g.dart
│ ├── screen
│ │ └── home_screen.dart
│ ├── service
│ │ └── departures_service.dart
│ ├── view
│ │ ├── contactCard
│ │ │ ├── contact_card_error_view.dart
│ │ │ ├── contact_card_loading_view.dart
│ │ │ ├── contact_card_unauthorized_view.dart
│ │ │ ├── contact_card_view.dart
│ │ │ ├── contact_view.dart
│ │ │ ├── link_view.dart
│ │ │ └── tuition_view.dart
│ │ ├── departure
│ │ │ ├── departures_details_row_view.dart
│ │ │ ├── departures_details_view.dart
│ │ │ └── departures_widget_view.dart
│ │ └── widget
│ │ │ ├── home_settings_view.dart
│ │ │ ├── preference_selection_view.dart
│ │ │ ├── widget_frame_view.dart
│ │ │ └── widget_screen.dart
│ └── viewmodel
│ │ ├── departures_viewmodel.dart
│ │ └── home_viewmodel.dart
├── main.dart
├── navigaTumComponent
│ ├── model
│ │ ├── details
│ │ │ ├── navigatum_navigation_additional_properties.dart
│ │ │ ├── navigatum_navigation_additional_properties.g.dart
│ │ │ ├── navigatum_navigation_coordinates.dart
│ │ │ ├── navigatum_navigation_coordinates.g.dart
│ │ │ ├── navigatum_navigation_maps.dart
│ │ │ ├── navigatum_navigation_maps.g.dart
│ │ │ ├── navigatum_overlays_maps.dart
│ │ │ ├── navigatum_overlays_maps.g.dart
│ │ │ ├── navigatum_roomfinder_maps.dart
│ │ │ └── navigatum_roomfinder_maps.g.dart
│ │ ├── navigatum_navigation_details.dart
│ │ ├── navigatum_navigation_details.g.dart
│ │ ├── navigatum_navigation_entity.dart
│ │ ├── navigatum_navigation_entity.g.dart
│ │ ├── navigatum_navigation_property.dart
│ │ ├── navigatum_navigation_property.g.dart
│ │ ├── navigatum_overlay_map.dart
│ │ ├── navigatum_overlay_map.g.dart
│ │ ├── navigatum_roomfinder_map.dart
│ │ ├── navigatum_roomfinder_map.g.dart
│ │ └── search
│ │ │ ├── navigatum_search_response.dart
│ │ │ ├── navigatum_search_response.g.dart
│ │ │ ├── navigatum_search_response_section.dart
│ │ │ └── navigatum_search_response_section.g.dart
│ ├── services
│ │ ├── navigatum_search_service.dart
│ │ └── navigatum_service.dart
│ ├── viewModels
│ │ ├── navigatum_campus_viewmodel.dart
│ │ └── navigatum_details_viewmodel.dart
│ └── views
│ │ ├── navigatum_room_building_view.dart
│ │ ├── navigatum_room_details_view.dart
│ │ ├── navigatum_room_maps_view.dart
│ │ └── navigatum_room_view.dart
├── navigation.dart
├── navigation_service.dart
├── onboardingComponent
│ ├── model
│ │ ├── confirm.dart
│ │ ├── confirm.g.dart
│ │ ├── token.dart
│ │ └── token.g.dart
│ ├── services
│ │ └── onboarding_service.dart
│ ├── viewModels
│ │ └── onboarding_viewmodel.dart
│ └── views
│ │ ├── confirm_view.dart
│ │ ├── location_permissions_view.dart
│ │ ├── login_view.dart
│ │ ├── permission_check_view.dart
│ │ └── permission_view.dart
├── personComponent
│ ├── model
│ │ ├── personDetails
│ │ │ ├── contact_info.dart
│ │ │ ├── contact_info.g.dart
│ │ │ ├── organisation.dart
│ │ │ ├── organisation.g.dart
│ │ │ ├── person_details.dart
│ │ │ ├── person_details.g.dart
│ │ │ ├── phone_extension.dart
│ │ │ ├── phone_extension.g.dart
│ │ │ ├── room.dart
│ │ │ └── room.g.dart
│ │ ├── personSearch
│ │ │ ├── person.dart
│ │ │ └── person.g.dart
│ │ └── profile
│ │ │ ├── profile.dart
│ │ │ ├── profile.g.dart
│ │ │ ├── tuition.dart
│ │ │ └── tuition.g.dart
│ ├── services
│ │ ├── person_details_service.dart
│ │ ├── person_search_service.dart
│ │ └── profile_service.dart
│ ├── viewModel
│ │ ├── person_details_viewmodel.dart
│ │ └── profile_viewmodel.dart
│ └── views
│ │ └── person_details_view.dart
├── placesComponent
│ ├── model
│ │ ├── cafeterias
│ │ │ ├── cafeteria.dart
│ │ │ ├── cafeteria.g.dart
│ │ │ ├── cafeteria_menu.dart
│ │ │ ├── dish.dart
│ │ │ ├── dish.g.dart
│ │ │ ├── meal_plan.dart
│ │ │ ├── meal_plan.g.dart
│ │ │ ├── mensa_menu.dart
│ │ │ ├── mensa_menu.g.dart
│ │ │ ├── opening_hours.dart
│ │ │ └── opening_hours.g.dart
│ │ └── studyRooms
│ │ │ ├── study_room.dart
│ │ │ ├── study_room.g.dart
│ │ │ ├── study_room_attribute.dart
│ │ │ ├── study_room_attribute.g.dart
│ │ │ ├── study_room_data.dart
│ │ │ ├── study_room_data.g.dart
│ │ │ ├── study_room_group.dart
│ │ │ ├── study_room_group.g.dart
│ │ │ ├── study_room_opening_hours.dart
│ │ │ └── study_room_opening_hours.g.dart
│ ├── services
│ │ ├── cafeterias_service.dart
│ │ ├── map_theme_service.dart
│ │ ├── mealplan_service.dart
│ │ └── study_rooms_service.dart
│ ├── viewModels
│ │ ├── cafeterias_viewmodel.dart
│ │ ├── places_viewmodel.dart
│ │ └── study_rooms_viewmodel.dart
│ └── views
│ │ ├── cafeterias
│ │ ├── cafeteria_row_view.dart
│ │ ├── cafeteria_view.dart
│ │ ├── cafeterias_view.dart
│ │ ├── dish_card_view.dart
│ │ ├── dish_grid_view.dart
│ │ └── dish_slider_view.dart
│ │ ├── campuses
│ │ ├── campus_card_view.dart
│ │ ├── campus_map_legend.dart
│ │ ├── campus_map_view.dart
│ │ ├── campus_most_searched_view.dart
│ │ ├── campus_scaffold.dart
│ │ └── campus_view.dart
│ │ ├── homeWidget
│ │ ├── cafeteria_widget_view.dart
│ │ └── study_room_widget_view.dart
│ │ ├── map_widget.dart
│ │ ├── places_screen.dart
│ │ ├── places_view.dart
│ │ └── studyGroups
│ │ ├── study_room_group_scaffold.dart
│ │ ├── study_room_group_view.dart
│ │ ├── study_room_row_view.dart
│ │ └── study_rooms_view.dart
├── searchComponent
│ ├── model
│ │ ├── comparison_token.dart
│ │ └── search_exception.dart
│ ├── protocols
│ │ ├── global_search.dart
│ │ ├── search_category_viewmodel.dart
│ │ └── searchable.dart
│ ├── viewModels
│ │ ├── search_viewmodel.dart
│ │ └── searchableViewModels
│ │ │ ├── cafeteria_search_viewmodel.dart
│ │ │ ├── calendar_search_viewmodel.dart
│ │ │ ├── grades_search_viewmodel.dart
│ │ │ ├── lecture_search_viewmodel.dart
│ │ │ ├── movie_search_viewmodel.dart
│ │ │ ├── navigatum_search_viewmodel.dart
│ │ │ ├── news_search_viewmodel.dart
│ │ │ ├── person_search_viewmodel.dart
│ │ │ ├── personal_lecture_seach_viewmodel.dart
│ │ │ ├── student_club_search_viewmodel.dart
│ │ │ └── study_room_search_viewmodel.dart
│ └── views
│ │ ├── resultViews
│ │ ├── cafeteria_search_result_view.dart
│ │ ├── calendar_search_result_view.dart
│ │ ├── grade_search_result_view.dart
│ │ ├── lecture_search_result_view.dart
│ │ ├── movie_search_result_view.dart
│ │ ├── navigatum_search_result_view.dart
│ │ ├── news_search_result_view.dart
│ │ ├── person_search_result_view.dart
│ │ ├── personal_lecture_search_result_view.dart
│ │ ├── student_club_search_result_view.dart
│ │ └── study_room_search_result_view.dart
│ │ ├── search_category_picker_view.dart
│ │ ├── search_result_card_view.dart
│ │ ├── search_result_details_view.dart
│ │ ├── search_result_view_builder.dart
│ │ ├── search_scaffold.dart
│ │ ├── search_textfield_view.dart
│ │ └── search_view.dart
├── settingsComponent
│ ├── viewModels
│ │ └── settings_viewmodel.dart
│ └── views
│ │ ├── appearance_settings_view.dart
│ │ ├── calendar_settings_view.dart
│ │ ├── contact_view.dart
│ │ ├── general_settings_view.dart
│ │ ├── settings_scaffold.dart
│ │ └── settings_view.dart
├── studentCardComponent
│ ├── model
│ │ ├── student_card.dart
│ │ └── student_card.g.dart
│ ├── services
│ │ └── student_card_service.dart
│ ├── viewModel
│ │ └── student_card_viewmodel.dart
│ └── views
│ │ ├── bar_code_view.dart
│ │ ├── information_view.dart
│ │ ├── snapping_slider.dart
│ │ ├── student_card_view.dart
│ │ └── verfication_code_view.dart
└── studiesComponent
│ ├── model
│ ├── average_grade.dart
│ ├── average_grade.g.dart
│ ├── grade.dart
│ ├── grade.g.dart
│ ├── lecture.dart
│ ├── lecture.g.dart
│ ├── lecture_details.dart
│ └── lecture_details.g.dart
│ ├── screen
│ └── studies_screen.dart
│ ├── service
│ ├── grade_service.dart
│ ├── lecture_details_service.dart
│ ├── lecture_search_service.dart
│ └── lecture_service.dart
│ ├── view
│ ├── grade
│ │ ├── chart_view.dart
│ │ ├── grade_rectangle.dart
│ │ ├── grade_view.dart
│ │ └── grades_view.dart
│ ├── lecture
│ │ ├── lecture_view.dart
│ │ └── lectures_view.dart
│ ├── lectureDetail
│ │ ├── basic_lecture_info_row_view.dart
│ │ ├── basic_lecture_info_view.dart
│ │ ├── detailed_lecture_info_row_view.dart
│ │ ├── detailed_lecture_info_view.dart
│ │ ├── lecture_details_view.dart
│ │ ├── lecture_info_card_view.dart
│ │ ├── lecture_links_view.dart
│ │ └── lecture_meeting_info_view.dart
│ └── semester_view.dart
│ └── viewModel
│ ├── grade_viewmodel.dart
│ ├── lecture_details_viewmodel.dart
│ └── lecture_viewmodel.dart
├── protos
├── google
│ └── api
│ │ ├── annotations.proto
│ │ └── http.proto
└── tumdev
│ └── campus_backend.proto
├── pubspec.lock
├── pubspec.yaml
└── test
└── api_test.dart
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributing
2 |
3 | We are glad that you are contributing to the TUM Campus App and are helping to enhance the user experience. Please make sure all your contributions adhere to the following guidelines:
4 |
5 | * Are able to be published under LICENCE_IS_TOO_BE_DISCUSSED. Don't use licensed material
6 | * Are your own creations or attributed correctly if not
7 | * The code is in a usable state and there are no Null Pointer Exceptions or similar acts of sabotage
8 | * Your code is *not* magic :sparkles:
9 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: TUM-Dev
4 | open_collective: tum-dev
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG] "
5 | labels: 'Bug :bug:'
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Smartphone (please complete the following information):**
27 | * Phone:
28 | * OS version:
29 | * Language:
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[Feature]"
5 | labels: 'Feature :tada:'
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Issue
2 |
3 | This fixes the following issue(s):
4 | - Resolves: #XXXX
5 |
6 | ## Screenshot
7 |
8 | ## Why this is useful for all students
9 |
10 |
--------------------------------------------------------------------------------
/.github/workflows/lint_test_build.yml:
--------------------------------------------------------------------------------
1 | name: Linting, Testing and Building
2 |
3 | on:
4 | push:
5 | branches-ignore:
6 | - "dev"
7 | - "main"
8 |
9 | jobs:
10 | build:
11 | runs-on: macos-13
12 |
13 | steps:
14 | - uses: actions/checkout@v3
15 |
16 | - name: Install latest CocoaPods Version
17 | run: sudo gem install cocoapods
18 |
19 | - name: Setup Flutter
20 | uses: subosito/flutter-action@v2
21 | with:
22 | channel: stable
23 |
24 | - name: Install Flutter Packages
25 | run: flutter pub get
26 |
27 | - name: Analyze Project
28 | run: dart analyze --fatal-warnings
29 |
30 | - name: Run Tests
31 | run: flutter test
32 |
33 | - name: Install CocoaPods
34 | run: cd ./ios && pod install
35 |
36 | - name: Install Java SDK
37 | uses: actions/setup-java@v3
38 | with:
39 | distribution: 'corretto'
40 | java-version: '17'
41 |
42 | - name: Build iOS
43 | run: flutter build ipa --no-codesign
44 |
45 | - name: Build Android
46 | run: flutter build apk
47 |
48 | #- name: Build Website
49 | # run: flutter build web --base-href /
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .build/
9 | .buildlog/
10 | .history
11 | .svn/
12 | .swiftpm/
13 | migrate_working_dir/
14 |
15 | # IntelliJ related
16 | *.iml
17 | *.ipr
18 | *.iws
19 | .idea/
20 |
21 | # The .vscode folder contains launch configuration and tasks you configure in
22 | # VS Code which you may wish to be included in version control, so this line
23 | # is commented out by default.
24 | .vscode/
25 |
26 | # Flutter/Dart/Pub related
27 | **/doc/api/
28 | **/ios/Flutter/.last_build_id
29 | .dart_tool/
30 | .flutter-plugins
31 | .flutter-plugins-dependencies
32 | .packages
33 | .pub-cache/
34 | .pub/
35 | /build/
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
48 | # fastlane related
49 | ios/Runner.app.dSYM.zip
50 | ios/Runner.ipa
51 | ios/fastlane/report.xml
52 | ios/fastlane/README.md
53 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 | Please report any and all security vulnerabilitys you found, or you think you found at app (at-symbol) tum.de .
6 | We will diagnose the issue internally and propose a fix.
7 | The timeline of a fix depends on how severe the problem is and what impacts it has.
8 | As a reward for reporting such vulnerabilitys you can get exclusive stickers or other small things.
9 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
3 | linter:
4 | rules:
5 | require_trailing_commas: true
6 | always_use_package_imports: true
7 |
8 | analyzer:
9 | errors:
10 | invalid_annotation_target: ignore
11 | exclude:
12 | - '**/*.g.dart'
13 | - lib/base/networking/apis/tumdev/campus_backend.pb.dart
14 | - lib/base/networking/apis/tumdev/campus_backend.pbenum.dart
15 | - lib/base/networking/apis/tumdev/campus_backend.pbgrpc.dart
16 | - lib/base/networking/apis/tumdev/campus_backend.pbjson.dart
17 | - lib/base/networking/apis/google/protobuf/empty.pbjson.dart
18 | - lib/base/networking/apis/google/protobuf/timestamp.pb.dart
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 | **/.cxx
9 |
10 | # Remember to never publicly share your keystore.
11 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
12 | key.properties
13 | **/*.keystore
14 | **/*.jks
15 |
16 | Gemfile.lock
17 |
--------------------------------------------------------------------------------
/android/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
4 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/de/tum/in/tumcampus/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package de.tum.`in`.tumcampus
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.content.pm.ActivityInfo
6 | import android.os.Bundle
7 | import io.flutter.embedding.android.FlutterActivity
8 |
9 |
10 | class MainActivity : FlutterActivity() {
11 | @SuppressLint("SourceLockedOrientationActivity")
12 | override fun onCreate(savedInstanceState: Bundle?) {
13 | if (isPhone(this)) {
14 | requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
15 | }
16 |
17 | super.onCreate(savedInstanceState)
18 | }
19 | }
20 |
21 | fun isPhone(context: Context): Boolean {
22 | val resources = context.resources
23 | val configuration = resources.configuration
24 | val screenWidthDp = configuration.screenWidthDp
25 | return screenWidthDp <= resources.getDimension(R.dimen.min_tablet_width_dp)
26 | }
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/de/tum/in/tumcampus/util/ColorExtension.kt:
--------------------------------------------------------------------------------
1 | package de.tum.`in`.tumcampus.util
2 |
3 | import android.graphics.Color
4 |
5 | fun argbToColor(argb: Long): Int {
6 | val alpha = ((argb shr 24) and 0xFF) / 255f
7 | val red = ((argb shr 16) and 0xFF) / 255f
8 | val green = ((argb shr 8) and 0xFF) / 255f
9 | val blue = (argb and 0xFF) / 255f
10 | return Color.argb(alpha, red, green, blue)
11 | }
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/de/tum/in/tumcampus/util/Const.kt:
--------------------------------------------------------------------------------
1 | package de.tum.`in`.tumcampus.util
2 |
3 | /**
4 | * Contains different constants used by several classes. Allows a unified access.
5 | */
6 | object Const {
7 | const val EVENT_TIME = "event_time"
8 | }
9 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/appwidget_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/drawable/appwidget_preview.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/rounded_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-v31/themes.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
13 |
14 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 | #FFE1F5FE
3 | #FF81D4FA
4 | #FF039BE5
5 | #FF01579B
6 |
7 | @color/tum_500
8 | @color/tum_700
9 |
10 | #0065BD
11 | #004C8E
12 |
13 | #030303
14 | #a5a5a5
15 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 10dp
4 | 8dp
5 | 4dp
6 | 2dp
7 | 600dp
8 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
12 |
13 |
17 |
--------------------------------------------------------------------------------
/android/app/src/main/res/xml-v31/calendar_widget_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/android/app/src/main/res/xml/calendar_widget_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | rootProject.buildDir = "../build"
9 | subprojects {
10 | project.buildDir = "${rootProject.buildDir}/${project.name}"
11 | }
12 | subprojects {
13 | project.evaluationDependsOn(":app")
14 | }
15 |
16 | tasks.register("clean", Delete) {
17 | delete rootProject.buildDir
18 | }
19 |
--------------------------------------------------------------------------------
/android/build/.last_build_id:
--------------------------------------------------------------------------------
1 | 5ac2f0046179d5c246a76aed8c877cba
--------------------------------------------------------------------------------
/android/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | package_name("de.tum.in.tumcampus")
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | android.nonTransitiveRClass=false
5 | android.nonFinalResIds=false
6 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }()
9 |
10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11 |
12 | repositories {
13 | google()
14 | mavenCentral()
15 | gradlePluginPortal()
16 | }
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21 | id "com.android.application" version '8.9.0' apply false
22 | id "org.jetbrains.kotlin.android" version "1.9.20" apply false
23 | id "org.jetbrains.kotlin.plugin.serialization" version "2.0.21" apply false
24 | id "com.google.gms.google-services" version "4.4.2" apply false
25 | id "com.google.firebase.crashlytics" version "3.0.3" apply false
26 | }
27 |
28 | include ":app"
29 |
--------------------------------------------------------------------------------
/assets/images/campus/campus-freising.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/campus/campus-freising.jpg
--------------------------------------------------------------------------------
/assets/images/campus/campus-garching.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/campus/campus-garching.jpeg
--------------------------------------------------------------------------------
/assets/images/campus/campus-klinikum.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/campus/campus-klinikum.jpg
--------------------------------------------------------------------------------
/assets/images/campus/campus-olympia.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/campus/campus-olympia.jpg
--------------------------------------------------------------------------------
/assets/images/campus/campus-stamm.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/campus/campus-stamm.jpeg
--------------------------------------------------------------------------------
/assets/images/location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/location.png
--------------------------------------------------------------------------------
/assets/images/logos/tum-logo-blue-text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/logos/tum-logo-blue-text.png
--------------------------------------------------------------------------------
/assets/images/logos/tum-logo-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/logos/tum-logo-blue.png
--------------------------------------------------------------------------------
/assets/images/logos/tum-logo-rainbow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/logos/tum-logo-rainbow.png
--------------------------------------------------------------------------------
/assets/images/logos/tum-logo-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/logos/tum-logo-white.png
--------------------------------------------------------------------------------
/assets/images/placeholders/movie_placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/placeholders/movie_placeholder.png
--------------------------------------------------------------------------------
/assets/images/placeholders/news_placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/placeholders/news_placeholder.png
--------------------------------------------------------------------------------
/assets/images/placeholders/portrait_placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/placeholders/portrait_placeholder.png
--------------------------------------------------------------------------------
/assets/images/placeholders/student_club_placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/placeholders/student_club_placeholder.png
--------------------------------------------------------------------------------
/assets/images/tower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/images/tower.png
--------------------------------------------------------------------------------
/assets/mapStyles/lightMapTheme.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "featureType": "poi.business",
4 | "stylers": [
5 | {
6 | "visibility": "off"
7 | }
8 | ]
9 | },
10 | {
11 | "featureType": "poi.park",
12 | "elementType": "labels.text",
13 | "stylers": [
14 | {
15 | "visibility": "off"
16 | }
17 | ]
18 | }
19 | ]
--------------------------------------------------------------------------------
/assets/videos/token-tutorial.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/assets/videos/token-tutorial.mp4
--------------------------------------------------------------------------------
/devtools_options.yaml:
--------------------------------------------------------------------------------
1 | description: This file stores settings for Dart & Flutter DevTools.
2 | documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
3 | extensions:
4 | - drift: true
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
36 | Gemfile.lock
37 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0xBC",
9 | "green" : "0x64",
10 | "red" : "0x00"
11 | }
12 | },
13 | "idiom" : "universal"
14 | },
15 | {
16 | "appearances" : [
17 | {
18 | "appearance" : "luminosity",
19 | "value" : "dark"
20 | }
21 | ],
22 | "color" : {
23 | "color-space" : "srgb",
24 | "components" : {
25 | "alpha" : "1.000",
26 | "blue" : "0xB3",
27 | "green" : "0x70",
28 | "red" : "0x30"
29 | }
30 | },
31 | "idiom" : "universal"
32 | }
33 | ],
34 | "info" : {
35 | "author" : "xcode",
36 | "version" : 1
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 2.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 3-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 3-1.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 3.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 4.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 5.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 6-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 6-1.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 6.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 7-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 7-1.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 7.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/CalendarWidget/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 8.png
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "1.000",
9 | "green" : "1.000",
10 | "red" : "1.000"
11 | }
12 | },
13 | "idiom" : "universal"
14 | },
15 | {
16 | "appearances" : [
17 | {
18 | "appearance" : "luminosity",
19 | "value" : "dark"
20 | }
21 | ],
22 | "color" : {
23 | "color-space" : "srgb",
24 | "components" : {
25 | "alpha" : "1.000",
26 | "blue" : "0.000",
27 | "green" : "0.000",
28 | "red" : "0.000"
29 | }
30 | },
31 | "idiom" : "universal"
32 | }
33 | ],
34 | "info" : {
35 | "author" : "xcode",
36 | "version" : 1
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/CalendarEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CalendarEntry.swift
3 | // Runner
4 | //
5 | // Created by Jakob Körber on 31.01.24.
6 | //
7 |
8 | import Foundation
9 | import SwiftUI
10 |
11 | struct CalendarEntry: Codable, Identifiable {
12 | let id: String
13 | let title: String
14 | let status: String
15 | let startDate: Date
16 | let endDate: Date
17 | let location: [String]
18 | let color: Int?
19 |
20 | enum CodingKeys: String, CodingKey {
21 | case id = "nr"
22 | case startDate = "dtstart"
23 | case endDate = "dtend"
24 | case title, location, status, color
25 | }
26 |
27 | var eventColor: Color {
28 | return color == nil ? .accent : Color(argb: UInt32(color!))
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/CalendarEventType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CalendarEventType.swift
3 | // CalendarWidgetExtension
4 | //
5 | // Created by Jakob Körber on 02.02.24.
6 | //
7 |
8 | import Foundation
9 |
10 | enum CalendarEventType {
11 | case canceled
12 | case lecture
13 | case exercise
14 | case other
15 | }
16 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/CalendarWidgetBundle.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CalendarWidgetBundle.swift
3 | // CalendarWidget
4 | //
5 | // Created by Jakob Körber on 31.01.24.
6 | //
7 |
8 | import WidgetKit
9 | import SwiftUI
10 |
11 | @main
12 | struct CalendarWidgetBundle: WidgetBundle {
13 | var body: some Widget {
14 | CalendarWidget()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/CalendarWidgetEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CalendarWidgetEntry.swift
3 | // CalendarWidgetExtension
4 | //
5 | // Created by Jakob Körber on 01.02.24.
6 | //
7 |
8 | import WidgetKit
9 | import SwiftUI
10 |
11 | struct CalendarWidgetEntry: TimelineEntry {
12 | let date: Date
13 | let entries: [CalendarEntry]
14 | let size: WidgetFamily
15 | }
16 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/ColorExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ColorExtension.swift
3 | // CalendarWidgetExtension
4 | //
5 | // Created by Jakob Körber on 03.04.24.
6 | //
7 |
8 | import Foundation
9 | import SwiftUI
10 |
11 | extension Color {
12 | init(argb: UInt32) {
13 | let alpha = Double((argb >> 24) & 0xFF) / 255.0
14 | let red = Double((argb >> 16) & 0xFF) / 255.0
15 | let green = Double((argb >> 8) & 0xFF) / 255.0
16 | let blue = Double(argb & 0xFF) / 255.0
17 | self.init(red: red, green: green, blue: blue, opacity: alpha)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/DateExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DateExtension.swift
3 | // CalendarWidgetExtension
4 | //
5 | // Created by Jakob Körber on 04.03.24.
6 | //
7 |
8 | import Foundation
9 |
10 | extension Date {
11 | var isToday: Bool {
12 | let calendar = Calendar.autoupdatingCurrent
13 | return calendar.isDateInToday(self)
14 | }
15 |
16 | var isTomorrow: Bool {
17 | let calendar = Calendar.autoupdatingCurrent
18 | return calendar.isDateInTomorrow(self)
19 | }
20 |
21 | var timeAgo: String? {
22 | let formatter = DateComponentsFormatter()
23 | formatter.unitsStyle = .full
24 | formatter.allowedUnits = [.year, .month, .day, .hour, .minute, .second]
25 | formatter.zeroFormattingBehavior = .dropAll
26 | formatter.maximumUnitCount = 1
27 | if (Date().timeIntervalSince(self) > 60) {
28 | return String(format: formatter.string(from: self, to: Date()) ?? "")
29 | } else {
30 | return nil
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ios/CalendarWidget/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSExtension
6 |
7 | NSExtensionPointIdentifier
8 | com.apple.widgetkit-extension
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ios/CalendarWidgetExtension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | group.de.tum.tca-widget
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 12.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 | import GoogleMaps
4 |
5 | @main
6 | @objc class AppDelegate: FlutterAppDelegate {
7 | override func application(
8 | _ application: UIApplication,
9 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
10 | ) -> Bool {
11 | GMSServices.provideAPIKey("AIzaSyAxUbnUMsXWVzeptXiLuNDMGpGEVFHLT4Y")
12 | GeneratedPluginRegistrant.register(with: self)
13 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 2.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 3-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 3-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 3.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 4.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 5.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 6-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 6-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 6.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 7-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 7-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 7.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/AppIcon.appiconset/slice1@3x copy 8.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "logo-white.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/logo-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TUM-Dev/campus_flutter/a840a546cd48ff207435650c125b2df07975acd7/ios/Runner/Assets.xcassets/LaunchImage.imageset/logo-white.png
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/ios/Runner/Runner.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 | com.apple.security.application-groups
8 |
9 | group.de.tum.tca-widget
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ios/build/.last_build_id:
--------------------------------------------------------------------------------
1 | 39f4bf50ad275767c79aa66def67de4c
--------------------------------------------------------------------------------
/ios/ci_scripts/ci_post_clone.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # by default, the execution directory of this script is the ci_scripts directory
4 | # CI_WORKSPACE is the directory of your cloned repo
5 | echo "🟩 Navigate from ($PWD) to ($CI_WORKSPACE)"
6 | cd $CI_WORKSPACE
7 |
8 | echo "🟩 Install Flutter"
9 | time git clone https://github.com/flutter/flutter.git -b stable $HOME/flutter
10 | export PATH="$PATH:$HOME/flutter/bin"
11 |
12 | echo "🟩 Flutter Precache"
13 | time flutter precache --ios
14 |
15 | echo "🟩 Install Flutter Dependencies"
16 | time flutter pub get
17 |
18 | echo "🟩 Install CocoaPods via Homebrew"
19 | time HOMEBREW_NO_AUTO_UPDATE=1 brew install cocoapods
20 |
21 | echo "🟩 Install CocoaPods dependencies..."
22 | time cd ios && pod install
23 |
24 | exit 0
--------------------------------------------------------------------------------
/ios/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | app_identifier("de.tum.tca")
2 | team_name("Technische Universitaet Muenchen")
3 | team_id("2J3C6P6X3N")
4 | itc_team_name("Technische Universitaet Muenchen")
5 | itc_team_id("850117")
--------------------------------------------------------------------------------
/ios/fastlane/Matchfile:
--------------------------------------------------------------------------------
1 | git_url("git@github.com:TUM-Dev/campus_flutter_match.git")
2 | storage_mode("git")
3 | type("appstore")
4 | app_identifier(["de.tum.tca", "de.tum.tca.calendarWidget"])
5 |
--------------------------------------------------------------------------------
/ios/firebase_app_id_file.json:
--------------------------------------------------------------------------------
1 | {
2 | "file_generated_by": "FlutterFire CLI",
3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
4 | "GOOGLE_APP_ID": "1:944892355389:ios:70b9e0e71c71af4b52db54",
5 | "FIREBASE_PROJECT_ID": "tca-backend-0001",
6 | "GCM_SENDER_ID": "944892355389"
7 | }
--------------------------------------------------------------------------------
/lib/base/enums/appearance.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | enum Appearance {
4 | system(Icons.devices, ThemeMode.system, "System", "System"),
5 | light(Icons.light_mode, ThemeMode.light, "Light", "Hell"),
6 | dark(Icons.dark_mode, ThemeMode.dark, "Dark", "Dunkel");
7 |
8 | final IconData icon;
9 | final ThemeMode themeMode;
10 | final String english;
11 | final String german;
12 |
13 | const Appearance(this.icon, this.themeMode, this.english, this.german);
14 | }
15 |
--------------------------------------------------------------------------------
/lib/base/enums/credentials.dart:
--------------------------------------------------------------------------------
1 | enum Credentials { none, noTumId, tumId }
2 |
--------------------------------------------------------------------------------
/lib/base/enums/device.dart:
--------------------------------------------------------------------------------
1 | enum Device { phone, portraitTablet, landscapeTablet }
2 |
--------------------------------------------------------------------------------
/lib/base/enums/error_handling_view_type.dart:
--------------------------------------------------------------------------------
1 | enum ErrorHandlingViewType {
2 | fullScreen,
3 | fullScreenNoImage,
4 | textOnly,
5 | descriptionOnly,
6 | redDescriptionOnly,
7 | }
8 |
--------------------------------------------------------------------------------
/lib/base/enums/gender.dart:
--------------------------------------------------------------------------------
1 | enum Gender { male, female, nonBinary, unknown }
2 |
--------------------------------------------------------------------------------
/lib/base/enums/home_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/widget_type.dart';
2 |
3 | class HomeScreenWidget {
4 | WidgetType widgetType;
5 | bool enabled;
6 |
7 | HomeScreenWidget({required this.widgetType, this.enabled = true});
8 |
9 | String convertToString() {
10 | return "${WidgetType.values.indexOf(widgetType)};${enabled.toString()}";
11 | }
12 |
13 | static HomeScreenWidget? fromString(String data) {
14 | final dataPoints = data.split(";");
15 | final index = int.parse(dataPoints[0]);
16 | if (index < WidgetType.values.length) {
17 | final widgetType = WidgetType.values[int.parse(dataPoints[0])];
18 | final enabled = dataPoints[1] == "true" ? true : false;
19 | return HomeScreenWidget(widgetType: widgetType, enabled: enabled);
20 | } else {
21 | return null;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/base/enums/remote_config_message.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_localization/easy_localization.dart';
2 | import 'package:flutter/cupertino.dart';
3 |
4 | enum RemoteConfigMessage {
5 | tumOnlineDegraded,
6 | tumOnlineMaintenance;
7 |
8 | String get firebaseId {
9 | switch (this) {
10 | case RemoteConfigMessage.tumOnlineDegraded:
11 | return "isTUMOnlineDegraded";
12 | case RemoteConfigMessage.tumOnlineMaintenance:
13 | return "isTUMOnlineMaintenanceMode";
14 | }
15 | }
16 |
17 | String message(BuildContext context) {
18 | switch (this) {
19 | case RemoteConfigMessage.tumOnlineDegraded:
20 | return context.tr("tumOnlineDegraded");
21 | case RemoteConfigMessage.tumOnlineMaintenance:
22 | return context.tr("tumOnlineMaintenance");
23 | }
24 | }
25 |
26 | static RemoteConfigMessage? fromString(String key) {
27 | if (key == "isTUMOnlineDegraded") {
28 | return RemoteConfigMessage.tumOnlineDegraded;
29 | } else if (key == "isTUMOnlineMaintenanceMode") {
30 | return RemoteConfigMessage.tumOnlineMaintenance;
31 | } else {
32 | return null;
33 | }
34 | }
35 |
36 | static Set get keys {
37 | return RemoteConfigMessage.values.map((e) => e.firebaseId).toSet();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/base/enums/role.dart:
--------------------------------------------------------------------------------
1 | enum Role {
2 | student("Student"),
3 | extern("Extern"),
4 | employee("Employee");
5 |
6 | final String name;
7 |
8 | const Role(this.name);
9 | }
10 |
--------------------------------------------------------------------------------
/lib/base/enums/search_type.dart:
--------------------------------------------------------------------------------
1 | enum SearchType { general, room, person }
2 |
--------------------------------------------------------------------------------
/lib/base/enums/user_preference.dart:
--------------------------------------------------------------------------------
1 | enum UserPreference {
2 | cafeteria(String),
3 | departure(int),
4 | studyRoom(int),
5 | homeWidgets(List),
6 | theme(int),
7 | calendarColors(String),
8 | browser(bool),
9 | studentCardPicture(bool),
10 | failedGrades(bool),
11 | weekends(bool),
12 | hiddenCalendarEntries(bool),
13 | calendarTab(int);
14 |
15 | final Type type;
16 |
17 | const UserPreference(this.type);
18 | }
19 |
--------------------------------------------------------------------------------
/lib/base/enums/widget_type.dart:
--------------------------------------------------------------------------------
1 | enum WidgetType { cafeterias, calendar, departures, studyRooms }
2 |
--------------------------------------------------------------------------------
/lib/base/errorHandling/default_error_router.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/error_handling_view_type.dart';
2 | import 'package:campus_flutter/base/errorHandling/error_handling_view.dart';
3 | import 'package:easy_localization/easy_localization.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class DefaultErrorRouter extends StatelessWidget with ErrorHandlingView {
7 | DefaultErrorRouter({
8 | super.key,
9 | required this.exception,
10 | required ErrorHandlingViewType errorHandlingViewType,
11 | Function()? retry,
12 | Color? titleColor,
13 | Color? bodyColor,
14 | }) {
15 | this.errorHandlingViewType = errorHandlingViewType;
16 | this.retry = retry;
17 | this.titleColor = titleColor;
18 | this.bodyColor = bodyColor;
19 | }
20 |
21 | final Object? exception;
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | return exceptionMessage(
26 | errorMessage: context.tr("unknownError"),
27 | fixMessage: context.tr("pleaseReport"),
28 | context: context,
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/base/errorHandling/grpc_error_router.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/error_handling_view_type.dart';
2 | import 'package:campus_flutter/base/errorHandling/error_handling_view.dart';
3 | import 'package:easy_localization/easy_localization.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:grpc/grpc.dart';
6 |
7 | class GrpcErrorRouter extends StatelessWidget with ErrorHandlingView {
8 | GrpcErrorRouter({
9 | super.key,
10 | required this.grpcError,
11 | required ErrorHandlingViewType errorHandlingViewType,
12 | Function()? retry,
13 | Color? titleColor,
14 | Color? bodyColor,
15 | }) {
16 | this.errorHandlingViewType = errorHandlingViewType;
17 | this.retry = retry;
18 | this.titleColor = titleColor;
19 | this.bodyColor = bodyColor;
20 | }
21 |
22 | final GrpcError grpcError;
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | return exceptionMessage(
27 | errorMessage: grpcError.message ?? context.tr("unknownError"),
28 | context: context,
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/base/errorHandling/search_exception_router.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/error_handling_view_type.dart';
2 | import 'package:campus_flutter/base/errorHandling/error_handling_view.dart';
3 | import 'package:campus_flutter/searchComponent/model/search_exception.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class SearchExceptionRouter extends StatelessWidget with ErrorHandlingView {
7 | SearchExceptionRouter({
8 | super.key,
9 | required this.searchException,
10 | required ErrorHandlingViewType errorHandlingViewType,
11 | Function()? retry,
12 | Color? titleColor,
13 | Color? bodyColor,
14 | }) {
15 | this.errorHandlingViewType = errorHandlingViewType;
16 | this.retry = retry;
17 | this.titleColor = titleColor;
18 | this.bodyColor = bodyColor;
19 | }
20 |
21 | final SearchException searchException;
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | return exceptionMessage(
26 | errorMessage: searchException.message,
27 | context: context,
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/base/errorHandling/type_error_router.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/error_handling_view_type.dart';
2 | import 'package:campus_flutter/base/errorHandling/error_handling_view.dart';
3 | import 'package:easy_localization/easy_localization.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class TypeErrorRouter extends StatelessWidget with ErrorHandlingView {
7 | TypeErrorRouter({
8 | super.key,
9 | required this.typeError,
10 | required ErrorHandlingViewType errorHandlingViewType,
11 | Function()? retry,
12 | Color? titleColor,
13 | Color? bodyColor,
14 | }) {
15 | this.errorHandlingViewType = errorHandlingViewType;
16 | this.retry = retry;
17 | this.titleColor = titleColor;
18 | this.bodyColor = bodyColor;
19 | }
20 |
21 | final TypeError typeError;
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | return exceptionMessage(
26 | errorMessage: context.tr("decodingError"),
27 | fixMessage: context.tr("pleaseReport"),
28 | context: context,
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/base/extensions/base_64_decode_image_data.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'package:flutter/foundation.dart';
3 |
4 | Uint8List base64DecodeImageData(String source) {
5 | var mutatedSource = source;
6 | mutatedSource = mutatedSource.replaceAll(r'\r\\n', "");
7 | mutatedSource = mutatedSource.replaceAll(r'\\n', "");
8 | return base64Decode(mutatedSource);
9 | }
10 |
--------------------------------------------------------------------------------
/lib/base/extensions/cast.dart:
--------------------------------------------------------------------------------
1 | T? cast(x) => x is T ? x : null;
2 |
--------------------------------------------------------------------------------
/lib/base/extensions/color.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | extension IntColorComponents on Color {
4 | int get intValue {
5 | return _floatToInt8(a) << 24 |
6 | _floatToInt8(r) << 16 |
7 | _floatToInt8(g) << 8 |
8 | _floatToInt8(b) << 0;
9 | }
10 |
11 | int get intAlpha => _floatToInt8(a);
12 | int get intRed => _floatToInt8(r);
13 | int get intGreen => _floatToInt8(g);
14 | int get intBlue => _floatToInt8(b);
15 |
16 | int _floatToInt8(double x) {
17 | return (x * 255.0).round() & 0xff;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/lib/base/extensions/context.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | extension ContextTheme on BuildContext {
4 | ThemeData get theme => Theme.of(this);
5 |
6 | double get halfPadding => 5.0;
7 |
8 | double get padding => 15.0;
9 |
10 | Color get primaryColor => Theme.of(this).primaryColor;
11 | }
12 |
--------------------------------------------------------------------------------
/lib/base/extensions/date_time.dart:
--------------------------------------------------------------------------------
1 | import 'package:intl/intl.dart';
2 |
3 | /// found here: https://stackoverflow.com/a/54129275/20473653
4 | extension NumberOfWeeks on DateTime {
5 | int _numOfWeeks(int year) {
6 | DateTime dec28 = DateTime(year, 12, 28);
7 | int dayOfDec28 = int.parse(DateFormat("D").format(dec28));
8 | return ((dayOfDec28 - dec28.weekday + 10) / 7).floor();
9 | }
10 |
11 | String weekNumber() {
12 | int dayOfYear = int.parse(DateFormat("D").format(this));
13 | int woy = ((dayOfYear - weekday + 10) / 7).floor();
14 | if (woy < 1) {
15 | woy = _numOfWeeks(year - 1);
16 | } else if (woy > _numOfWeeks(year)) {
17 | woy = 1;
18 | }
19 | return woy.toString().padLeft(2, "0");
20 | }
21 | }
22 |
23 | extension SameDay on DateTime {
24 | bool isAtSameDay(DateTime dateTime) {
25 | return day == dateTime.day &&
26 | month == dateTime.month &&
27 | year == dateTime.year;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/base/extensions/latlng_to_json.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:google_maps_flutter/google_maps_flutter.dart';
4 |
5 | extension JsonString on LatLng {
6 | static String? toJsonString(LatLng? latLng) {
7 | if (latLng == null) {
8 | return null;
9 | } else {
10 | return const JsonEncoder().convert(latLng.toJson());
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/base/extensions/locale_fullname.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | extension FullName on Locale {
4 | String fullName() {
5 | switch (languageCode) {
6 | case 'en':
7 | return 'English';
8 | case 'de':
9 | return 'Deutsch';
10 | }
11 | return 'Unknown';
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/base/extensions/string_capitalize.dart:
--------------------------------------------------------------------------------
1 | /// found on https://stackoverflow.com/a/60528001
2 | extension StringExtension on String {
3 | String capitalizeFirstLetter() {
4 | return "${this[0].toUpperCase()}${substring(1)}";
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/lib/base/extensions/string_levenshtein.dart:
--------------------------------------------------------------------------------
1 | extension Levenshtein on String {
2 | int levenshtein(String comparisonToken) {
3 | if (isEmpty && comparisonToken.isEmpty) {
4 | return 0;
5 | } else if (isEmpty) {
6 | return comparisonToken.length;
7 | } else if (comparisonToken.isEmpty) {
8 | return length;
9 | }
10 |
11 | List a = split('');
12 | List b = comparisonToken.split('');
13 |
14 | List> dist = List.generate(
15 | a.length + 1,
16 | (_) => List.filled(b.length + 1, 0),
17 | );
18 |
19 | for (int i = 1; i <= a.length; i++) {
20 | dist[i][0] = i;
21 | }
22 |
23 | for (int j = 1; j <= b.length; j++) {
24 | dist[0][j] = j;
25 | }
26 |
27 | for (int i = 1; i <= a.length; i++) {
28 | for (int j = 1; j <= b.length; j++) {
29 | if (a[i - 1] == b[j - 1]) {
30 | dist[i][j] = dist[i - 1][j - 1]; // Noop
31 | } else {
32 | dist[i][j] = [
33 | dist[i - 1][j] + 1, // Deletion
34 | dist[i][j - 1] + 1, // Insertion
35 | dist[i - 1][j - 1] + 1, // Substitution
36 | ].reduce((min, current) => current < min ? current : min);
37 | }
38 | }
39 | }
40 |
41 | return dist[a.length][b.length];
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/lib/base/extensions/string_remove_diacritics.dart:
--------------------------------------------------------------------------------
1 | extension RemoveDiacritics on String {
2 | /// found on: https://stackoverflow.com/a/64742829
3 | String removeDiacritics() {
4 | String string = this;
5 |
6 | var withDia =
7 | 'ÀÁÂÃÄÅàáâãäåÒÓÔÕÕÖØòóôõöøÈÉÊËèéêëðÇçÐÌÍÎÏìíîïÙÚÛÜùúûüÑñŠšŸÿýŽž';
8 | var withoutDia =
9 | 'AAAAAAaaaaaaOOOOOOOooooooEEEEeeeeeCcDIIIIiiiiUUUUuuuuNnSsYyyZz';
10 |
11 | for (int i = 0; i < withDia.length; i++) {
12 | string = string.replaceAll(withDia[i], withoutDia[i]);
13 | }
14 |
15 | return string;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/lib/base/extensions/string_valid_chars.dart:
--------------------------------------------------------------------------------
1 | extension ValidChars on String {
2 | String keepValidChars() {
3 | return replaceAll(RegExp(r'[^a-zA-Z0-9 ]'), '');
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/eatApi/eat_api.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/eatApi/eat_api_endpoint.dart';
2 | import 'package:campus_flutter/base/networking/protocols/api.dart';
3 |
4 | class EatApi extends Api {
5 | final EatApiEndpoint eatApiEndpoint;
6 |
7 | EatApi(this.eatApiEndpoint);
8 |
9 | @override
10 | String get domain => "tum-dev.github.io";
11 |
12 | @override
13 | String get path => "eat-api/";
14 |
15 | @override
16 | String get slug {
17 | switch (eatApiEndpoint) {
18 | case EatApiEndpointCanteens _:
19 | return "enums/canteens.json";
20 | case EatApiEndpointLanguages _:
21 | return "enums/languages.json";
22 | case EatApiEndpointLabels _:
23 | return "enums/labels.json";
24 | case EatApiEndpointAll _:
25 | return "all.json";
26 | case EatApiEndpointAllRef _:
27 | return "all_ref.json";
28 | case EatApiEndpointMenu menu:
29 | return "${menu.location}/${menu.year}/${menu.week.toString().padLeft(1, "0")}.json";
30 | }
31 | }
32 |
33 | @override
34 | Map get parameters => {};
35 |
36 | @override
37 | bool get needsAuth => false;
38 | }
39 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/eatApi/eat_api_endpoint.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/extensions/date_time.dart';
2 |
3 | sealed class EatApiEndpoint {}
4 |
5 | class EatApiEndpointCanteens extends EatApiEndpoint {}
6 |
7 | class EatApiEndpointLanguages extends EatApiEndpoint {}
8 |
9 | class EatApiEndpointLabels extends EatApiEndpoint {}
10 |
11 | class EatApiEndpointAll extends EatApiEndpoint {}
12 |
13 | class EatApiEndpointAllRef extends EatApiEndpoint {}
14 |
15 | class EatApiEndpointMenu extends EatApiEndpoint {
16 | final String location;
17 | final int year;
18 | final String week;
19 |
20 | EatApiEndpointMenu({required this.location, int? year, String? week})
21 | : year = year ?? DateTime.now().year,
22 | week = week ?? DateTime.now().weekNumber();
23 | }
24 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/google/protobuf/empty.pbenum.dart:
--------------------------------------------------------------------------------
1 | //
2 | // Generated code. Do not modify.
3 | // source: google/protobuf/empty.proto
4 | //
5 | // @dart = 2.12
6 |
7 | // ignore_for_file: annotate_overrides, camel_case_types, comment_references
8 | // ignore_for_file: constant_identifier_names, library_prefixes
9 | // ignore_for_file: non_constant_identifier_names, prefer_final_fields
10 | // ignore_for_file: unnecessary_import, unnecessary_this, unused_import
11 |
12 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/google/protobuf/empty.pbjson.dart:
--------------------------------------------------------------------------------
1 | //
2 | // Generated code. Do not modify.
3 | // source: google/protobuf/empty.proto
4 | //
5 | // @dart = 2.12
6 |
7 | // ignore_for_file: annotate_overrides, camel_case_types, comment_references
8 | // ignore_for_file: constant_identifier_names, library_prefixes
9 | // ignore_for_file: non_constant_identifier_names, prefer_final_fields
10 | // ignore_for_file: unnecessary_import, unnecessary_this, unused_import
11 |
12 | import 'dart:convert' as $convert;
13 | import 'dart:core' as $core;
14 | import 'dart:typed_data' as $typed_data;
15 |
16 | @$core.Deprecated('Use emptyDescriptor instead')
17 | const Empty$json = {
18 | '1': 'Empty',
19 | };
20 |
21 | /// Descriptor for `Empty`. Decode as a `google.protobuf.DescriptorProto`.
22 | final $typed_data.Uint8List emptyDescriptor = $convert.base64Decode(
23 | 'CgVFbXB0eQ==');
24 |
25 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/google/protobuf/timestamp.pbenum.dart:
--------------------------------------------------------------------------------
1 | //
2 | // Generated code. Do not modify.
3 | // source: google/protobuf/timestamp.proto
4 | //
5 | // @dart = 2.12
6 |
7 | // ignore_for_file: annotate_overrides, camel_case_types, comment_references
8 | // ignore_for_file: constant_identifier_names, library_prefixes
9 | // ignore_for_file: non_constant_identifier_names, prefer_final_fields
10 | // ignore_for_file: unnecessary_import, unnecessary_this, unused_import
11 |
12 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/google/protobuf/timestamp.pbjson.dart:
--------------------------------------------------------------------------------
1 | //
2 | // Generated code. Do not modify.
3 | // source: google/protobuf/timestamp.proto
4 | //
5 | // @dart = 2.12
6 |
7 | // ignore_for_file: annotate_overrides, camel_case_types, comment_references
8 | // ignore_for_file: constant_identifier_names, library_prefixes
9 | // ignore_for_file: non_constant_identifier_names, prefer_final_fields
10 | // ignore_for_file: unnecessary_import, unnecessary_this, unused_import
11 |
12 | import 'dart:convert' as $convert;
13 | import 'dart:core' as $core;
14 | import 'dart:typed_data' as $typed_data;
15 |
16 | @$core.Deprecated('Use timestampDescriptor instead')
17 | const Timestamp$json = {
18 | '1': 'Timestamp',
19 | '2': [
20 | {'1': 'seconds', '3': 1, '4': 1, '5': 3, '10': 'seconds'},
21 | {'1': 'nanos', '3': 2, '4': 1, '5': 5, '10': 'nanos'},
22 | ],
23 | };
24 |
25 | /// Descriptor for `Timestamp`. Decode as a `google.protobuf.DescriptorProto`.
26 | final $typed_data.Uint8List timestampDescriptor = $convert.base64Decode(
27 | 'CglUaW1lc3RhbXASGAoHc2Vjb25kcxgBIAEoA1IHc2Vjb25kcxIUCgVuYW5vcxgCIAEoBVIFbm'
28 | 'Fub3M=');
29 |
30 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/irisApi/iris_api.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/irisApi/iris_api_endpoint.dart';
2 | import 'package:campus_flutter/base/networking/protocols/api.dart';
3 |
4 | class IrisApi extends Api {
5 | final IrisApiEndpoint irisApiEndpoint;
6 |
7 | IrisApi({required this.irisApiEndpoint});
8 |
9 | @override
10 | String get domain => "iris.asta.tum.de";
11 |
12 | @override
13 | bool get needsAuth => false;
14 |
15 | @override
16 | Map get parameters => irisApiEndpoint.getParameters();
17 |
18 | @override
19 | String get path => "";
20 |
21 | @override
22 | String get slug => "api";
23 | }
24 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/irisApi/iris_api_endpoint.dart:
--------------------------------------------------------------------------------
1 | sealed class IrisApiEndpoint {
2 | Map getParameters() => {};
3 | }
4 |
5 | class IrisApiEndpointRooms extends IrisApiEndpoint {}
6 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/mvvDeparturesApi/mvv_departures_api.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/protocols/api.dart';
2 |
3 | class MvvDeparturesApi extends Api {
4 | final String station;
5 | final int? walkingTime;
6 |
7 | MvvDeparturesApi({required this.station, required this.walkingTime});
8 |
9 | @override
10 | String get domain => "efa.mvv-muenchen.de";
11 |
12 | @override
13 | bool get needsAuth => false;
14 |
15 | @override
16 | Map get parameters => {
17 | "outputFormat": "JSON",
18 | "language": "en",
19 | "stateless": "1",
20 | "coordOutputFormat": "WGS84",
21 | "type_dm": "stop",
22 | "name_dm": station,
23 | if (walkingTime != null) "timeOffset": walkingTime.toString(),
24 | "useRealtime": "1",
25 | "itOptionsActive": "1",
26 | "ptOptionsActive": "1",
27 | "limit": "20",
28 | "mergeDep": "1",
29 | "useAllStops": "1",
30 | "mode": "direct",
31 | };
32 |
33 | @override
34 | String get path => "ng/";
35 |
36 | @override
37 | String get slug => "XML_DM_REQUEST";
38 | }
39 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/navigaTumApi/navigatum_api.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/navigaTumApi/navigatum_api_endpoint.dart';
2 | import 'package:campus_flutter/base/networking/protocols/api.dart';
3 |
4 | class NavigaTumApi extends Api {
5 | final NavigaTumApiEndpoint navigaTumApiEndpoint;
6 |
7 | NavigaTumApi({required this.navigaTumApiEndpoint});
8 |
9 | @override
10 | String get domain => "nav.tum.de";
11 |
12 | @override
13 | bool get needsAuth => false;
14 |
15 | @override
16 | Map get parameters => navigaTumApiEndpoint.getParameters();
17 |
18 | @override
19 | String get path => "";
20 |
21 | @override
22 | String get slug {
23 | switch (navigaTumApiEndpoint) {
24 | case NavigaTumApiEndpointSearch _:
25 | return "api/search";
26 | case NavigaTumApiEndpointDetails details:
27 | return "api/locations/${details.id}";
28 | case NavigaTumApiEndpointImages images:
29 | return "cdn/maps/roomfinder/${images.id}";
30 | case NavigaTumApiEndpointOverlayImages overlayImages:
31 | return "cdn/maps/roomfinder/${overlayImages.id}";
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/base/networking/apis/navigaTumApi/navigatum_api_endpoint.dart:
--------------------------------------------------------------------------------
1 | sealed class NavigaTumApiEndpoint {
2 | Map getParameters() => {};
3 | }
4 |
5 | class NavigaTumApiEndpointSearch extends NavigaTumApiEndpoint {
6 | final String query;
7 |
8 | NavigaTumApiEndpointSearch({required this.query});
9 |
10 | @override
11 | Map getParameters() => {"q": query};
12 | }
13 |
14 | class NavigaTumApiEndpointDetails extends NavigaTumApiEndpoint {
15 | final String id;
16 | final String language;
17 |
18 | NavigaTumApiEndpointDetails({required this.id, required this.language});
19 |
20 | @override
21 | Map getParameters() => {"lang": language};
22 | }
23 |
24 | class NavigaTumApiEndpointImages extends NavigaTumApiEndpoint {
25 | final String id;
26 |
27 | NavigaTumApiEndpointImages({required this.id});
28 | }
29 |
30 | class NavigaTumApiEndpointOverlayImages extends NavigaTumApiEndpoint {
31 | final String id;
32 |
33 | NavigaTumApiEndpointOverlayImages({required this.id});
34 | }
35 |
--------------------------------------------------------------------------------
/lib/base/networking/base/api_response.dart:
--------------------------------------------------------------------------------
1 | class ApiResponse {
2 | T data;
3 | DateTime? saved;
4 |
5 | ApiResponse({required this.data, this.saved});
6 |
7 | factory ApiResponse.fromJson(
8 | dynamic json,
9 | Map extras,
10 | Function(Map) create,
11 | ) {
12 | if (json is List) {
13 | return ApiResponse(
14 | data: create({"data": json}),
15 | saved: extras["saved"] as DateTime?,
16 | );
17 | } else {
18 | return ApiResponse(
19 | data: create(json),
20 | saved: extras["saved"] as DateTime?,
21 | );
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/base/networking/protocols/api_exception.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:json_annotation/json_annotation.dart';
4 |
5 | part 'api_exception.g.dart';
6 |
7 | abstract class ApiException implements Exception {
8 | String message(BuildContext? context, WidgetRef? ref);
9 |
10 | String? recoverySuggestion(BuildContext context, WidgetRef ref);
11 |
12 | Function()? overwriteRetry(BuildContext context);
13 |
14 | String? overwriteRetryMessage(BuildContext context);
15 | }
16 |
17 | @JsonSerializable()
18 | class ExceptionBody {
19 | @JsonKey(name: "error")
20 | final ExceptionMessage exceptionMessage;
21 |
22 | ExceptionBody({required this.exceptionMessage});
23 |
24 | factory ExceptionBody.fromJson(Map json) =>
25 | _$ExceptionBodyFromJson(json);
26 |
27 | Map toJson() => _$ExceptionBodyToJson(this);
28 | }
29 |
30 | @JsonSerializable()
31 | class ExceptionMessage {
32 | final String message;
33 |
34 | ExceptionMessage({required this.message});
35 |
36 | factory ExceptionMessage.fromJson(Map json) =>
37 | _$ExceptionMessageFromJson(json);
38 |
39 | Map toJson() => _$ExceptionMessageToJson(this);
40 | }
41 |
--------------------------------------------------------------------------------
/lib/base/networking/protocols/api_exception.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'api_exception.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | ExceptionBody _$ExceptionBodyFromJson(Map json) =>
10 | ExceptionBody(
11 | exceptionMessage: ExceptionMessage.fromJson(
12 | json['error'] as Map,
13 | ),
14 | );
15 |
16 | Map _$ExceptionBodyToJson(ExceptionBody instance) =>
17 | {'error': instance.exceptionMessage};
18 |
19 | ExceptionMessage _$ExceptionMessageFromJson(Map json) =>
20 | ExceptionMessage(message: json['message'] as String);
21 |
22 | Map _$ExceptionMessageToJson(ExceptionMessage instance) =>
23 | {'message': instance.message};
24 |
--------------------------------------------------------------------------------
/lib/base/services/connection_service.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | class ConnectionService {
4 | bool _hasInternet = true;
5 | DateTime? _dateTime;
6 |
7 | ConnectionService() {
8 | checkConnection();
9 | }
10 |
11 | Future checkConnection() async {
12 | if (_dateTime != null &&
13 | _dateTime!.difference(DateTime.now()).inSeconds < 30) {
14 | return _hasInternet;
15 | } else {
16 | _hasInternet = await _lookupInternetAddress();
17 | return _hasInternet;
18 | }
19 | }
20 |
21 | Future _lookupInternetAddress() {
22 | _dateTime = DateTime.now();
23 | return InternetAddress.lookup("google.com").then(
24 | (value) =>
25 | _hasInternet = (value.isNotEmpty && value[0].rawAddress.isNotEmpty),
26 | onError: (_) => false,
27 | );
28 | }
29 |
30 | bool hasInternet() {
31 | checkConnection();
32 | return _hasInternet;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/base/services/device_type_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/device.dart';
2 | import 'package:flutter/cupertino.dart';
3 |
4 | class DeviceService {
5 | static Device getType(BuildContext context) {
6 | return MediaQuery.orientationOf(context) == Orientation.landscape
7 | ? Device.landscapeTablet
8 | : MediaQuery.sizeOf(context).width > 600
9 | ? Device.portraitTablet
10 | : Device.phone;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/lib/base/services/location_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:geolocator/geolocator.dart';
2 |
3 | /// Determine the current position of the device.
4 | ///
5 | /// When the location services are not enabled or permissions
6 | /// are denied the `Future` will return an error.
7 | class LocationService {
8 | static Future determinePosition() async {
9 | bool serviceEnabled;
10 | LocationPermission permission;
11 |
12 | serviceEnabled = await Geolocator.isLocationServiceEnabled();
13 | if (!serviceEnabled) {
14 | return Future.error("Location Service disabled");
15 | }
16 |
17 | permission = await Geolocator.checkPermission();
18 | if (permission == LocationPermission.denied) {
19 | permission = await Geolocator.requestPermission();
20 | if (permission == LocationPermission.deniedForever) {
21 | return Future.error("Permission forever denied");
22 | }
23 |
24 | if (permission == LocationPermission.denied) {
25 | return Future.error("Permission denied");
26 | }
27 | }
28 |
29 | return await Geolocator.getCurrentPosition();
30 | }
31 |
32 | static Future getLastKnown() async {
33 | try {
34 | return await Geolocator.getLastKnownPosition();
35 | } catch (_) {
36 | return null;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/base/theme/constants.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | const Color primaryLightColor = Color(0xff0064BC);
4 | const Color primaryDarkColor = Color(0xff3070B3);
5 | const Color lightBackground = Color(0xfff2f2f7);
6 | const Color darkBackground = Color(0xff191919);
7 | const Color lightGray = Color(0xffAAAAAA);
8 | const Color navigationIconGrayLight = Color(0xffA0A0A1);
9 | const Color navigationIconGrayDark = Color(0xff808080);
10 | const Color darkGray = Color(0xff555555);
11 | const Color almostBlack = Color(0xff1a1c1e);
12 | const Color almostWhite = Color(0xffe3e2e6);
13 |
--------------------------------------------------------------------------------
/lib/base/util/custom_back_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/routing/routes.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:go_router/go_router.dart';
4 |
5 | class CustomBackButton extends StatelessWidget {
6 | const CustomBackButton({
7 | super.key,
8 | this.beforeOnPressed,
9 | this.onPressed,
10 | this.color,
11 | });
12 |
13 | final Function()? onPressed;
14 | final Function()? beforeOnPressed;
15 | final Color? color;
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return BackButton(
20 | color: color,
21 | onPressed: () {
22 | if (beforeOnPressed != null) {
23 | beforeOnPressed!();
24 | }
25 |
26 | if (onPressed != null) {
27 | onPressed!();
28 | } else {
29 | defaultOnPressed(context);
30 | }
31 | },
32 | );
33 | }
34 |
35 | void defaultOnPressed(BuildContext context) {
36 | context.canPop() ? context.pop() : context.go(home);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/base/util/days_parser.dart:
--------------------------------------------------------------------------------
1 | import 'dart:core';
2 |
3 | List decodeDaysBitmask(String bitmaskString) {
4 | final bitmask = int.tryParse(bitmaskString);
5 | if (bitmask == null) {
6 | return [];
7 | }
8 |
9 | final decodedDays = [];
10 |
11 | for (int i = 0; i < 7; i++) {
12 | if (bitmask & (1 << i) != 0) {
13 | decodedDays.add(i + 1);
14 | }
15 | }
16 |
17 | return decodedDays;
18 | }
19 |
20 | String getDayOfWeek(int dayNumber) {
21 | final daysOfWeek = [
22 | 'monday',
23 | 'tuesday',
24 | 'wednesday',
25 | 'thursday',
26 | 'friday',
27 | 'saturday',
28 | 'sunday',
29 | ];
30 | return daysOfWeek[dayNumber - 1];
31 | }
32 |
--------------------------------------------------------------------------------
/lib/base/util/enum_parser.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/shortcut_item.dart';
2 | import 'package:collection/collection.dart';
3 |
4 | class EnumParser {
5 | static ShortcutItemType typeFromString(String string) {
6 | return ShortcutItemType.values.firstWhereOrNull((e) => e.type == string) ??
7 | ShortcutItemType.home;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/base/util/fast_hash.dart:
--------------------------------------------------------------------------------
1 | /// as found on https://isar.dev/recipes/string_ids.html#fast-hash-function
2 | int fastHash(String string) {
3 | var hash = 0xcbf29ce484222325;
4 |
5 | var i = 0;
6 | while (i < string.length) {
7 | final codeUnit = string.codeUnitAt(i++);
8 | hash ^= codeUnit >> 8;
9 | hash *= 0x100000001b3;
10 | hash ^= codeUnit & 0xFF;
11 | hash *= 0x100000001b3;
12 | }
13 |
14 | return hash;
15 | }
16 |
--------------------------------------------------------------------------------
/lib/base/util/grid_utility.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/device.dart';
2 | import 'package:campus_flutter/base/services/device_type_service.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | class GridUtility {
6 | static int campusCrossAxisCount(BuildContext context) {
7 | switch (DeviceService.getType(context)) {
8 | case Device.landscapeTablet:
9 | return 6;
10 | case Device.portraitTablet:
11 | return 4;
12 | case Device.phone:
13 | return 2;
14 | }
15 | }
16 |
17 | static int campusPaddedCrossAxisCount(BuildContext context) {
18 | switch (DeviceService.getType(context)) {
19 | case Device.landscapeTablet:
20 | return 3;
21 | case Device.portraitTablet:
22 | return 4;
23 | case Device.phone:
24 | return 2;
25 | }
26 | }
27 |
28 | static int campusNumberOfItems(BuildContext context) {
29 | switch (DeviceService.getType(context)) {
30 | case Device.landscapeTablet:
31 | return 6;
32 | case Device.portraitTablet:
33 | return 8;
34 | case Device.phone:
35 | return 6;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/base/util/info_row.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/extensions/context.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class InfoRow extends StatelessWidget {
5 | const InfoRow({super.key, required this.title, required this.info});
6 |
7 | final String title;
8 | final String info;
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | return Row(
13 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
14 | children: [
15 | Expanded(
16 | child: Text(
17 | title,
18 | style: const TextStyle(fontWeight: FontWeight.w500),
19 | ),
20 | ),
21 | Padding(padding: EdgeInsets.symmetric(horizontal: context.halfPadding)),
22 | Expanded(child: Text(info)),
23 | ],
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/base/util/last_updated_text.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_localization/easy_localization.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_riverpod/flutter_riverpod.dart';
4 | import 'package:timeago/timeago.dart' as timeago;
5 |
6 | class LastUpdatedText extends ConsumerWidget {
7 | const LastUpdatedText(this.dateTime, {super.key});
8 |
9 | final DateTime dateTime;
10 |
11 | @override
12 | Widget build(BuildContext context, WidgetRef ref) {
13 | timeago.setLocaleMessages("de", timeago.DeMessages());
14 | return Center(
15 | child: Text(
16 | context.tr(
17 | "lastUpdatedAt",
18 | args: [
19 | timeago.format(
20 | dateTime,
21 | locale: Localizations.localeOf(context).languageCode,
22 | ),
23 | ],
24 | ),
25 | style: Theme.of(
26 | context,
27 | ).textTheme.bodySmall?.copyWith(color: Colors.grey.shade600),
28 | maxLines: 1,
29 | overflow: TextOverflow.ellipsis,
30 | ),
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/base/util/padded_divider.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/extensions/context.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class PaddedDivider extends StatelessWidget {
5 | const PaddedDivider({super.key, this.height});
6 |
7 | final double? height;
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Padding(
12 | padding: EdgeInsets.symmetric(horizontal: context.padding),
13 | child: Divider(height: height),
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/base/util/placeholder_text.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class PlaceholderText extends StatelessWidget {
4 | const PlaceholderText({super.key, required this.text, this.style});
5 |
6 | final String text;
7 | final TextStyle? style;
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | var textSize = _calcTextSize(context);
12 | return Container(
13 | height: textSize.height,
14 | width: textSize.width,
15 | color: Colors.grey,
16 | );
17 | }
18 |
19 | /// found on: https://stackoverflow.com/a/63133637
20 | Size _calcTextSize(BuildContext context) {
21 | final TextPainter textPainter = TextPainter(
22 | text: TextSpan(text: text, style: style),
23 | textDirection: TextDirection.ltr,
24 | textScaler: MediaQuery.textScalerOf(context),
25 | )..layout();
26 | return textPainter.size;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/base/util/read_list_value.dart:
--------------------------------------------------------------------------------
1 | List readListValue(Map data, String key) {
2 | final relevantData = data[key];
3 | if (relevantData is List) {
4 | return relevantData;
5 | } else if (relevantData is Map || relevantData is String) {
6 | return [relevantData];
7 | } else {
8 | return [];
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/lib/base/util/semester_calculator.dart:
--------------------------------------------------------------------------------
1 | class SemesterCalculator {
2 | static String getCurrentSemester() {
3 | final date = DateTime.now();
4 | if (date.isBefore(DateTime(date.year, 4, 1))) {
5 | final year = (date.year - 1).toString().substring(2, 4);
6 | return "${year}W";
7 | } else if (date.isBefore(DateTime(date.year, 9, 1))) {
8 | final year = (date.year).toString().substring(2, 4);
9 | return "${year}S";
10 | } else {
11 | final year = (date.year).toString().substring(2, 4);
12 | return "${year}W";
13 | }
14 | }
15 |
16 | static String getPriorSemester() {
17 | final date = DateTime.now();
18 | if (date.isBefore(DateTime(date.year, 4, 1))) {
19 | final year = (date.year - 1).toString().substring(2, 4);
20 | return "${year}S";
21 | } else if (date.isBefore(DateTime(date.year, 9, 1))) {
22 | final year = (date.year - 1).toString().substring(2, 4);
23 | return "${year}W";
24 | } else {
25 | final year = (date.year).toString().substring(2, 4);
26 | return "${year}S";
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/base/util/shimmer_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:shimmer/shimmer.dart';
3 |
4 | class ShimmerView extends StatelessWidget {
5 | final Widget child;
6 |
7 | const ShimmerView({super.key, required this.child});
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Shimmer.fromColors(
12 | baseColor:
13 | MediaQuery.of(context).platformBrightness == Brightness.light
14 | ? Colors.grey.shade300
15 | : Colors.grey.shade800,
16 | highlightColor:
17 | MediaQuery.of(context).platformBrightness == Brightness.light
18 | ? Colors.grey.shade100
19 | : Colors.grey.shade600,
20 | child: child,
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/base/util/speaker.dart:
--------------------------------------------------------------------------------
1 | class Speaker {
2 | static String getSpeakerName(String speakerString) {
3 | final speakers = speakerString.split(", ");
4 | final mainSpeaker = speakers.first.split(" [L]");
5 | return mainSpeaker.first.split(" (").first;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/lib/base/util/url_launcher.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:campus_flutter/settingsComponent/views/settings_view.dart';
4 | import 'package:flutter_riverpod/flutter_riverpod.dart';
5 | import 'package:url_launcher/url_launcher.dart';
6 | import 'package:url_launcher/url_launcher_string.dart';
7 |
8 | class UrlLauncher {
9 | static urlString(String urlString, WidgetRef ref) async {
10 | if (await canLaunchUrlString(urlString)) {
11 | if (ref.read(useWebView)) {
12 | launchUrlString(urlString, mode: LaunchMode.inAppBrowserView).onError(
13 | (error, stackTrace) =>
14 | launchUrlString(urlString, mode: LaunchMode.externalApplication),
15 | );
16 | } else {
17 | launchUrlString(urlString, mode: LaunchMode.externalApplication);
18 | }
19 | }
20 | }
21 |
22 | static url(Uri url, WidgetRef ref) async {
23 | if (await canLaunchUrl(url)) {
24 | if (ref.read(useWebView) && Platform.isIOS) {
25 | launchUrl(url, mode: LaunchMode.inAppWebView).onError(
26 | (error, stackTrace) =>
27 | launchUrl(url, mode: LaunchMode.externalApplication),
28 | );
29 | } else {
30 | launchUrl(url, mode: LaunchMode.externalApplication);
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/calendarComponent/model/calendar_preferences.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'calendar_preferences.g.dart';
4 |
5 | @JsonSerializable()
6 | class CalendarPreferences {
7 | final Map colorPreferences;
8 | final Map visibilityPreferences;
9 |
10 | CalendarPreferences(this.colorPreferences, this.visibilityPreferences);
11 |
12 | factory CalendarPreferences.fromJson(Map json) =>
13 | _$CalendarPreferencesFromJson(json);
14 |
15 | Map toJson() => _$CalendarPreferencesToJson(this);
16 | }
17 |
--------------------------------------------------------------------------------
/lib/calendarComponent/model/calendar_preferences.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'calendar_preferences.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | CalendarPreferences _$CalendarPreferencesFromJson(Map json) =>
10 | CalendarPreferences(
11 | Map.from(json['colorPreferences'] as Map),
12 | Map.from(json['visibilityPreferences'] as Map),
13 | );
14 |
15 | Map _$CalendarPreferencesToJson(
16 | CalendarPreferences instance,
17 | ) => {
18 | 'colorPreferences': instance.colorPreferences,
19 | 'visibilityPreferences': instance.visibilityPreferences,
20 | };
21 |
--------------------------------------------------------------------------------
/lib/calendarComponent/views/visibility_button_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/calendarComponent/viewModels/calendar_viewmodel.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_riverpod/flutter_riverpod.dart';
4 |
5 | class VisibilityButtonView extends ConsumerStatefulWidget {
6 | const VisibilityButtonView({
7 | super.key,
8 | required this.id,
9 | required this.isVisible,
10 | });
11 |
12 | final String id;
13 | final bool? isVisible;
14 |
15 | @override
16 | ConsumerState createState() =>
17 | _VisibilityButtonViewState();
18 | }
19 |
20 | class _VisibilityButtonViewState extends ConsumerState {
21 | late bool isVisible = widget.isVisible ?? true;
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | return InkWell(
26 | onTap: () {
27 | ref.read(calendarViewModel).toggleEventVisibility(widget.id);
28 | setState(() {
29 | isVisible = !isVisible;
30 | });
31 | },
32 | child: Icon((isVisible) ? Icons.visibility : Icons.visibility_off),
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/campusComponent/model/student_club.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pb.dart';
2 | import 'package:html/parser.dart';
3 |
4 | extension ParsedStudentClub on StudentClub {
5 | String get parsedName => parseFragment(name).text ?? name;
6 | }
7 |
--------------------------------------------------------------------------------
/lib/campusComponent/model/student_club_collection.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pb.dart';
2 | import 'package:html/parser.dart';
3 |
4 | extension ParsedStudentClubCollection on StudentClubCollection {
5 | String get parsedTitle => parseFragment(title).text ?? title;
6 | }
7 |
--------------------------------------------------------------------------------
/lib/campusComponent/service/movie_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/google/protobuf/timestamp.pb.dart';
2 | import 'package:campus_flutter/base/networking/base/grpc_client.dart';
3 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pbgrpc.dart';
4 | import 'package:campus_flutter/main.dart';
5 |
6 | class MovieService {
7 | static Future<(DateTime?, List)> fetchMovies(
8 | bool forcedRefresh,
9 | ) async {
10 | final currentDate = DateTime.now();
11 | GrpcClient grpcClient = getIt();
12 | final response = await grpcClient.listMovies(
13 | ListMoviesRequest(oldestDateAt: Timestamp.fromDateTime(currentDate)),
14 | );
15 | return (currentDate, response.movies);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/lib/campusComponent/service/news_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/google/protobuf/timestamp.pb.dart';
2 | import 'package:campus_flutter/base/networking/base/grpc_client.dart';
3 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pbgrpc.dart';
4 | import 'package:campus_flutter/main.dart';
5 |
6 | class NewsService {
7 | static Future<(DateTime?, List)> fetchRecentNews(
8 | bool forcedRefresh,
9 | ) async {
10 | final start = DateTime.now();
11 | GrpcClient grpcClient = getIt();
12 | final news = await grpcClient.listNews(
13 | ListNewsRequest(
14 | oldestDateAt: Timestamp.fromDateTime(
15 | DateTime(
16 | start.year,
17 | start.month,
18 | start.day,
19 | ).subtract(const Duration(days: 30)),
20 | ),
21 | ),
22 | );
23 | return (start, news.news);
24 | }
25 |
26 | static Future<(DateTime?, List)> fetchNews(bool forcedRefresh) async {
27 | final start = DateTime.now();
28 | GrpcClient grpcClient = getIt();
29 | final news = await grpcClient.listNews(ListNewsRequest());
30 | return (start, news.news);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/campusComponent/service/student_club_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pb.dart';
2 | import 'package:campus_flutter/base/networking/base/grpc_client.dart';
3 | import 'package:campus_flutter/main.dart';
4 |
5 | class StudentClubService {
6 | static Future<(DateTime?, List)> fetchStudentClubs(
7 | Language? language,
8 | bool forceRefresh,
9 | ) async {
10 | final start = DateTime.now();
11 | GrpcClient grpcClient = getIt();
12 | final response = await grpcClient.listStudentClub(
13 | ListStudentClubRequest(language: language),
14 | );
15 | return (start, response.collections);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/lib/campusComponent/view/movie/movie_grid_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/extensions/context.dart';
2 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pb.dart';
3 | import 'package:campus_flutter/campusComponent/view/movie/movie_card_view.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class MovieGridView extends StatelessWidget {
7 | const MovieGridView({
8 | super.key,
9 | required this.movies,
10 | required this.padding,
11 | required this.crossAxisCount,
12 | required this.withinScrollView,
13 | });
14 |
15 | final List movies;
16 | final EdgeInsets padding;
17 | final int crossAxisCount;
18 | final bool withinScrollView;
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return GridView.count(
23 | shrinkWrap: withinScrollView,
24 | physics: withinScrollView ? NeverScrollableScrollPhysics() : null,
25 | padding: padding,
26 | crossAxisCount: crossAxisCount,
27 | mainAxisSpacing: context.padding,
28 | crossAxisSpacing: context.padding,
29 | childAspectRatio: 250 / 470,
30 | children: [for (var movie in movies) MovieCardView(movie: movie)],
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/campusComponent/view/studentClub/student_club_grid_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/extensions/context.dart';
2 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pb.dart';
3 | import 'package:campus_flutter/campusComponent/view/studentClub/student_club_card_view.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class StudentClubGridView extends StatelessWidget {
7 | const StudentClubGridView({
8 | super.key,
9 | required this.studentClubs,
10 | required this.padding,
11 | required this.crossAxisCount,
12 | required this.withinScrollView,
13 | });
14 |
15 | final List studentClubs;
16 | final EdgeInsets padding;
17 | final int crossAxisCount;
18 | final bool withinScrollView;
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return GridView.count(
23 | shrinkWrap: withinScrollView,
24 | physics: withinScrollView ? NeverScrollableScrollPhysics() : null,
25 | padding: padding,
26 | mainAxisSpacing: context.padding,
27 | crossAxisSpacing: context.padding,
28 | crossAxisCount: crossAxisCount,
29 | children: [
30 | for (var studentClub in studentClubs)
31 | StudentClubCardView(studentClub: studentClub),
32 | ],
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/campusComponent/viewmodel/movies_viewmodel.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pbgrpc.dart';
2 | import 'package:campus_flutter/campusComponent/service/movie_service.dart';
3 | import 'package:flutter_riverpod/flutter_riverpod.dart';
4 | import 'package:rxdart/rxdart.dart';
5 |
6 | final movieViewModel = Provider((ref) => MovieViewModel());
7 |
8 | class MovieViewModel {
9 | final BehaviorSubject?> movies = BehaviorSubject.seeded(null);
10 | final BehaviorSubject lastFetched = BehaviorSubject.seeded(null);
11 |
12 | Future fetch(bool forcedRefresh) async {
13 | return MovieService.fetchMovies(forcedRefresh).then((response) {
14 | lastFetched.add(response.$1);
15 | movies.add(response.$2);
16 | }, onError: (error) => movies.addError(error));
17 | }
18 | }
19 |
20 | extension MovieTitle on Movie {
21 | String get movieTitle {
22 | final titleParts = title.split(": ");
23 | return titleParts.length == 2 ? titleParts[1] : title;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/lib/feedbackComponent/services/feedback_service.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:campus_flutter/base/networking/base/grpc_client.dart';
4 | import 'package:campus_flutter/base/networking/apis/tumdev/campus_backend.pbgrpc.dart';
5 | import 'package:campus_flutter/main.dart';
6 |
7 | class FeedbackService {
8 | static Future sendFeedback(
9 | CreateFeedbackRequest createFeedbackRequest,
10 | ) async {
11 | GrpcClient restClient = getIt();
12 | return await restClient.createFeedback(Stream.value(createFeedbackRequest));
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/lib/feedbackComponent/views/feedback_checkmark_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:rxdart/rxdart.dart';
4 |
5 | class FeedbackCheckMarkView extends ConsumerWidget {
6 | const FeedbackCheckMarkView({
7 | super.key,
8 | required this.text,
9 | required this.isChecked,
10 | });
11 |
12 | final String text;
13 | final BehaviorSubject isChecked;
14 |
15 | @override
16 | Widget build(BuildContext context, WidgetRef ref) {
17 | return StreamBuilder(
18 | stream: isChecked,
19 | builder: (context, snapshot) {
20 | return ListTile(
21 | dense: true,
22 | title: Text(text),
23 | trailing: Checkbox(
24 | value: snapshot.data ?? false,
25 | onChanged: (newValue) => isChecked.add(newValue ?? false),
26 | ),
27 | );
28 | },
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/homeComponent/model/departures_preference.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/enums/campus.dart';
2 | import 'package:campus_flutter/homeComponent/model/station.dart';
3 | import 'package:json_annotation/json_annotation.dart';
4 |
5 | part 'departures_preference.g.dart';
6 |
7 | @JsonSerializable()
8 | class DeparturesPreference {
9 | final Map preferences;
10 |
11 | DeparturesPreference({required this.preferences});
12 |
13 | factory DeparturesPreference.fromJson(Map json) =>
14 | _$DeparturesPreferenceFromJson(json);
15 |
16 | Map toJson() => _$DeparturesPreferenceToJson(this);
17 | }
18 |
--------------------------------------------------------------------------------
/lib/homeComponent/model/departures_preference.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'departures_preference.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | DeparturesPreference _$DeparturesPreferenceFromJson(
10 | Map json,
11 | ) => DeparturesPreference(
12 | preferences: (json['preferences'] as Map).map(
13 | (k, e) => MapEntry(
14 | $enumDecode(_$CampusEnumMap, k),
15 | Station.fromJson(e as Map),
16 | ),
17 | ),
18 | );
19 |
20 | Map _$DeparturesPreferenceToJson(
21 | DeparturesPreference instance,
22 | ) => {
23 | 'preferences': instance.preferences.map(
24 | (k, e) => MapEntry(_$CampusEnumMap[k]!, e),
25 | ),
26 | };
27 |
28 | const _$CampusEnumMap = {
29 | Campus.stammgelaende: 'stammgelaende',
30 | Campus.olympiapark: 'olympiapark',
31 | Campus.klinikumRechts: 'klinikumRechts',
32 | Campus.grosshadern: 'grosshadern',
33 | Campus.garching: 'garching',
34 | Campus.freising: 'freising',
35 | };
36 |
--------------------------------------------------------------------------------
/lib/homeComponent/model/mvv_response.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/homeComponent/model/departure.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'mvv_response.g.dart';
5 |
6 | @JsonSerializable()
7 | class MvvResponse {
8 | @JsonKey(name: "departureList", readValue: readDepartures)
9 | final List departures;
10 |
11 | MvvResponse({required this.departures});
12 |
13 | factory MvvResponse.fromJson(Map json) =>
14 | _$MvvResponseFromJson(json);
15 |
16 | Map toJson() => _$MvvResponseToJson(this);
17 |
18 | static List readDepartures(Map data, String key) {
19 | final relevantData = data[key];
20 | if (relevantData is List) {
21 | return relevantData;
22 | } else if (relevantData is Map) {
23 | return [relevantData["departure"]];
24 | } else {
25 | return [];
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/homeComponent/model/mvv_response.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'mvv_response.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | MvvResponse _$MvvResponseFromJson(Map json) => MvvResponse(
10 | departures:
11 | (MvvResponse.readDepartures(json, 'departureList') as List)
12 | .map((e) => Departure.fromJson(e as Map))
13 | .toList(),
14 | );
15 |
16 | Map _$MvvResponseToJson(MvvResponse instance) =>
17 | {'departureList': instance.departures};
18 |
--------------------------------------------------------------------------------
/lib/homeComponent/model/station.dart:
--------------------------------------------------------------------------------
1 | import 'package:google_maps_flutter/google_maps_flutter.dart';
2 | import 'package:campus_flutter/base/extensions/latlng_to_json.dart';
3 | import 'package:json_annotation/json_annotation.dart';
4 |
5 | part 'station.g.dart';
6 |
7 | @JsonSerializable()
8 | /// local data type
9 | class Station {
10 | final String name;
11 | final String apiName;
12 | @JsonKey(fromJson: LatLng.fromJson, toJson: JsonString.toJsonString)
13 | final LatLng? location;
14 |
15 | Station({required this.name, required this.apiName, this.location});
16 |
17 | factory Station.fromJson(Map json) =>
18 | _$StationFromJson(json);
19 |
20 | Map toJson() => _$StationToJson(this);
21 | }
22 |
--------------------------------------------------------------------------------
/lib/homeComponent/model/station.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'station.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Station _$StationFromJson(Map json) => Station(
10 | name: json['name'] as String,
11 | apiName: json['apiName'] as String,
12 | location: LatLng.fromJson(json['location']),
13 | );
14 |
15 | Map _$StationToJson(Station instance) => {
16 | 'name': instance.name,
17 | 'apiName': instance.apiName,
18 | 'location': JsonString.toJsonString(instance.location),
19 | };
20 |
--------------------------------------------------------------------------------
/lib/homeComponent/service/departures_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/mvvDeparturesApi/mvv_departures_api.dart';
2 | import 'package:campus_flutter/base/networking/base/rest_client.dart';
3 | import 'package:campus_flutter/homeComponent/model/mvv_response.dart';
4 | import 'package:campus_flutter/main.dart';
5 |
6 | class DeparturesService {
7 | static Future<({DateTime? saved, MvvResponse data})> fetchDepartures(
8 | bool forcedRefresh,
9 | String station,
10 | int? walkingTime,
11 | ) async {
12 | RestClient restClient = getIt();
13 | final response = await restClient.get(
14 | MvvDeparturesApi(station: station, walkingTime: walkingTime),
15 | MvvResponse.fromJson,
16 | forcedRefresh,
17 | );
18 |
19 | return (saved: response.saved, data: response.data);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib/homeComponent/view/contactCard/contact_card_error_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:easy_localization/easy_localization.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class ContactCardErrorView extends StatelessWidget {
5 | const ContactCardErrorView({super.key});
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | return Padding(
10 | padding: const EdgeInsets.all(10.0),
11 | child: Row(
12 | children: [
13 | const CircleAvatar(
14 | backgroundImage: AssetImage(
15 | 'assets/images/placeholders/portrait_placeholder.png',
16 | ),
17 | radius: 50,
18 | ),
19 | const Padding(padding: EdgeInsets.only(left: 15)),
20 | Expanded(
21 | child: Text(
22 | context.tr("profileError"),
23 | style: Theme.of(context).textTheme.titleLarge,
24 | textAlign: TextAlign.center,
25 | ),
26 | ),
27 | ],
28 | ),
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/homeComponent/view/contactCard/contact_card_unauthorized_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/routing/routes.dart';
2 | import 'package:easy_localization/easy_localization.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:go_router/go_router.dart';
5 |
6 | class ContactCardUnauthorizedView extends StatelessWidget {
7 | const ContactCardUnauthorizedView({super.key});
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return InkWell(
12 | onTap: () => context.push(onboarding),
13 | child: Padding(
14 | padding: const EdgeInsets.all(10.0),
15 | child: Row(
16 | children: [
17 | const CircleAvatar(
18 | backgroundImage: AssetImage(
19 | 'assets/images/placeholders/portrait_placeholder.png',
20 | ),
21 | radius: 50,
22 | ),
23 | const Padding(padding: EdgeInsets.only(left: 15)),
24 | Expanded(
25 | child: Text(
26 | context.tr("notLoggedIn"),
27 | style: Theme.of(context).textTheme.titleLarge,
28 | textAlign: TextAlign.center,
29 | ),
30 | ),
31 | ],
32 | ),
33 | ),
34 | );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lib/homeComponent/view/widget/preference_selection_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/extensions/context.dart';
2 | import 'package:campus_flutter/base/util/padded_divider.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | class PreferenceSelectionView extends StatelessWidget {
6 | const PreferenceSelectionView({
7 | super.key,
8 | required this.data,
9 | required this.entry,
10 | });
11 |
12 | final List data;
13 | final String entry;
14 |
15 | @override
16 | Widget build(BuildContext context) {
17 | return SingleChildScrollView(
18 | child: Padding(
19 | padding: EdgeInsets.only(bottom: context.padding * 2),
20 | child: Card(
21 | child: ListView.separated(
22 | physics: const NeverScrollableScrollPhysics(),
23 | shrinkWrap: true,
24 | padding: EdgeInsets.zero,
25 | itemBuilder: (context, index) => data[index],
26 | separatorBuilder:
27 | (context, index) => const PaddedDivider(height: 0),
28 | itemCount: data.length,
29 | ),
30 | ),
31 | ),
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_navigation_additional_properties.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/navigaTumComponent/model/navigatum_navigation_property.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'navigatum_navigation_additional_properties.g.dart';
5 |
6 | @JsonSerializable()
7 | class NavigaTumNavigationAdditionalProperties {
8 | @JsonKey(name: "computed")
9 | final List properties;
10 |
11 | NavigaTumNavigationAdditionalProperties(this.properties);
12 |
13 | factory NavigaTumNavigationAdditionalProperties.fromJson(
14 | Map json,
15 | ) => _$NavigaTumNavigationAdditionalPropertiesFromJson(json);
16 |
17 | Map toJson() =>
18 | _$NavigaTumNavigationAdditionalPropertiesToJson(this);
19 | }
20 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_navigation_additional_properties.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_navigation_additional_properties.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumNavigationAdditionalProperties
10 | _$NavigaTumNavigationAdditionalPropertiesFromJson(Map json) =>
11 | NavigaTumNavigationAdditionalProperties(
12 | (json['computed'] as List)
13 | .map(
14 | (e) =>
15 | NavigaTumNavigationProperty.fromJson(e as Map),
16 | )
17 | .toList(),
18 | );
19 |
20 | Map _$NavigaTumNavigationAdditionalPropertiesToJson(
21 | NavigaTumNavigationAdditionalProperties instance,
22 | ) => {'computed': instance.properties};
23 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_navigation_coordinates.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'navigatum_navigation_coordinates.g.dart';
4 |
5 | @JsonSerializable()
6 | class NavigaTumNavigationCoordinates {
7 | @JsonKey(name: "lat")
8 | final double? latitude;
9 | @JsonKey(name: "lon")
10 | final double? longitude;
11 |
12 | NavigaTumNavigationCoordinates(this.latitude, this.longitude);
13 |
14 | factory NavigaTumNavigationCoordinates.fromJson(Map json) =>
15 | _$NavigaTumNavigationCoordinatesFromJson(json);
16 |
17 | Map toJson() => _$NavigaTumNavigationCoordinatesToJson(this);
18 | }
19 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_navigation_coordinates.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_navigation_coordinates.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumNavigationCoordinates _$NavigaTumNavigationCoordinatesFromJson(
10 | Map json,
11 | ) => NavigaTumNavigationCoordinates(
12 | (json['lat'] as num?)?.toDouble(),
13 | (json['lon'] as num?)?.toDouble(),
14 | );
15 |
16 | Map _$NavigaTumNavigationCoordinatesToJson(
17 | NavigaTumNavigationCoordinates instance,
18 | ) => {'lat': instance.latitude, 'lon': instance.longitude};
19 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_navigation_maps.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/navigaTumComponent/model/details/navigatum_overlays_maps.dart';
2 | import 'package:campus_flutter/navigaTumComponent/model/details/navigatum_roomfinder_maps.dart';
3 | import 'package:json_annotation/json_annotation.dart';
4 |
5 | part 'navigatum_navigation_maps.g.dart';
6 |
7 | @JsonSerializable()
8 | class NavigaTumNavigationMaps {
9 | @JsonKey(name: "default")
10 | final String defaultMapId;
11 | final NavigaTumRoomFinderMaps? roomfinder;
12 | final NavigaTumOverlayMaps? overlays;
13 |
14 | NavigaTumNavigationMaps(this.defaultMapId, this.roomfinder, this.overlays);
15 |
16 | factory NavigaTumNavigationMaps.fromJson(Map json) =>
17 | _$NavigaTumNavigationMapsFromJson(json);
18 |
19 | Map toJson() => _$NavigaTumNavigationMapsToJson(this);
20 | }
21 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_navigation_maps.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_navigation_maps.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumNavigationMaps _$NavigaTumNavigationMapsFromJson(
10 | Map json,
11 | ) => NavigaTumNavigationMaps(
12 | json['default'] as String,
13 | json['roomfinder'] == null
14 | ? null
15 | : NavigaTumRoomFinderMaps.fromJson(
16 | json['roomfinder'] as Map,
17 | ),
18 | json['overlays'] == null
19 | ? null
20 | : NavigaTumOverlayMaps.fromJson(json['overlays'] as Map),
21 | );
22 |
23 | Map _$NavigaTumNavigationMapsToJson(
24 | NavigaTumNavigationMaps instance,
25 | ) => {
26 | 'default': instance.defaultMapId,
27 | 'roomfinder': instance.roomfinder,
28 | 'overlays': instance.overlays,
29 | };
30 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_overlays_maps.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/navigaTumComponent/model/navigatum_overlay_map.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'navigatum_overlays_maps.g.dart';
5 |
6 | @JsonSerializable()
7 | class NavigaTumOverlayMaps {
8 | final List available;
9 |
10 | NavigaTumOverlayMaps(this.available);
11 |
12 | factory NavigaTumOverlayMaps.fromJson(Map json) =>
13 | _$NavigaTumOverlayMapsFromJson(json);
14 |
15 | Map toJson() => _$NavigaTumOverlayMapsToJson(this);
16 | }
17 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_overlays_maps.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_overlays_maps.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumOverlayMaps _$NavigaTumOverlayMapsFromJson(
10 | Map json,
11 | ) => NavigaTumOverlayMaps(
12 | (json['available'] as List)
13 | .map((e) => NavigaTumOverlayMap.fromJson(e as Map))
14 | .toList(),
15 | );
16 |
17 | Map _$NavigaTumOverlayMapsToJson(
18 | NavigaTumOverlayMaps instance,
19 | ) => {'available': instance.available};
20 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_roomfinder_maps.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/navigaTumComponent/model/navigatum_roomfinder_map.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'navigatum_roomfinder_maps.g.dart';
5 |
6 | @JsonSerializable()
7 | class NavigaTumRoomFinderMaps {
8 | final List available;
9 | @JsonKey(name: "default")
10 | final String defaultMapId;
11 |
12 | NavigaTumRoomFinderMaps(this.available, this.defaultMapId);
13 |
14 | factory NavigaTumRoomFinderMaps.fromJson(Map json) =>
15 | _$NavigaTumRoomFinderMapsFromJson(json);
16 |
17 | Map toJson() => _$NavigaTumRoomFinderMapsToJson(this);
18 | }
19 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/details/navigatum_roomfinder_maps.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_roomfinder_maps.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumRoomFinderMaps _$NavigaTumRoomFinderMapsFromJson(
10 | Map json,
11 | ) => NavigaTumRoomFinderMaps(
12 | (json['available'] as List)
13 | .map((e) => NavigaTumRoomFinderMap.fromJson(e as Map))
14 | .toList(),
15 | json['default'] as String,
16 | );
17 |
18 | Map _$NavigaTumRoomFinderMapsToJson(
19 | NavigaTumRoomFinderMaps instance,
20 | ) => {
21 | 'available': instance.available,
22 | 'default': instance.defaultMapId,
23 | };
24 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/navigatum_navigation_entity.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_navigation_entity.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumNavigationEntity _$NavigaTumNavigationEntityFromJson(
10 | Map json,
11 | ) => NavigaTumNavigationEntity(
12 | id: json['id'] as String,
13 | type: json['type'] as String,
14 | name: json['name'] as String,
15 | subtext: json['subtext'] as String,
16 | parsedId: json['parsed_id'] as String?,
17 | );
18 |
19 | Map _$NavigaTumNavigationEntityToJson(
20 | NavigaTumNavigationEntity instance,
21 | ) => {
22 | 'id': instance.id,
23 | 'type': instance.type,
24 | 'name': instance.name,
25 | 'subtext': instance.subtext,
26 | 'parsed_id': instance.parsedId,
27 | };
28 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/navigatum_navigation_property.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'navigatum_navigation_property.g.dart';
4 |
5 | @JsonSerializable()
6 | class NavigaTumNavigationProperty {
7 | final String name;
8 | final String text;
9 |
10 | NavigaTumNavigationProperty({required this.name, required this.text});
11 |
12 | factory NavigaTumNavigationProperty.fromJson(Map json) =>
13 | _$NavigaTumNavigationPropertyFromJson(json);
14 |
15 | Map toJson() => _$NavigaTumNavigationPropertyToJson(this);
16 | }
17 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/navigatum_navigation_property.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_navigation_property.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumNavigationProperty _$NavigaTumNavigationPropertyFromJson(
10 | Map json,
11 | ) => NavigaTumNavigationProperty(
12 | name: json['name'] as String,
13 | text: json['text'] as String,
14 | );
15 |
16 | Map _$NavigaTumNavigationPropertyToJson(
17 | NavigaTumNavigationProperty instance,
18 | ) => {'name': instance.name, 'text': instance.text};
19 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/navigatum_overlay_map.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'navigatum_overlay_map.g.dart';
4 |
5 | @JsonSerializable()
6 | class NavigaTumOverlayMap {
7 | final int id;
8 | final String floor;
9 | @JsonKey(name: "file")
10 | final String imageUrl;
11 | final String name;
12 |
13 | NavigaTumOverlayMap(this.id, this.floor, this.imageUrl, this.name);
14 |
15 | factory NavigaTumOverlayMap.fromJson(Map json) =>
16 | _$NavigaTumOverlayMapFromJson(json);
17 |
18 | Map toJson() => _$NavigaTumOverlayMapToJson(this);
19 | }
20 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/navigatum_overlay_map.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_overlay_map.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumOverlayMap _$NavigaTumOverlayMapFromJson(Map json) =>
10 | NavigaTumOverlayMap(
11 | (json['id'] as num).toInt(),
12 | json['floor'] as String,
13 | json['file'] as String,
14 | json['name'] as String,
15 | );
16 |
17 | Map _$NavigaTumOverlayMapToJson(
18 | NavigaTumOverlayMap instance,
19 | ) => {
20 | 'id': instance.id,
21 | 'floor': instance.floor,
22 | 'file': instance.imageUrl,
23 | 'name': instance.name,
24 | };
25 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/navigatum_roomfinder_map.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'navigatum_roomfinder_map.g.dart';
4 |
5 | @JsonSerializable()
6 | class NavigaTumRoomFinderMap {
7 | final String id;
8 | final String name;
9 | @JsonKey(name: "file")
10 | final String imageUrl;
11 | final int height;
12 | final int width;
13 | final int x;
14 | final int y;
15 | final String scale;
16 |
17 | NavigaTumRoomFinderMap({
18 | required this.id,
19 | required this.name,
20 | required this.imageUrl,
21 | required this.height,
22 | required this.width,
23 | required this.x,
24 | required this.y,
25 | required this.scale,
26 | });
27 |
28 | factory NavigaTumRoomFinderMap.fromJson(Map json) =>
29 | _$NavigaTumRoomFinderMapFromJson(json);
30 |
31 | Map toJson() => _$NavigaTumRoomFinderMapToJson(this);
32 | }
33 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/navigatum_roomfinder_map.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_roomfinder_map.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumRoomFinderMap _$NavigaTumRoomFinderMapFromJson(
10 | Map json,
11 | ) => NavigaTumRoomFinderMap(
12 | id: json['id'] as String,
13 | name: json['name'] as String,
14 | imageUrl: json['file'] as String,
15 | height: (json['height'] as num).toInt(),
16 | width: (json['width'] as num).toInt(),
17 | x: (json['x'] as num).toInt(),
18 | y: (json['y'] as num).toInt(),
19 | scale: json['scale'] as String,
20 | );
21 |
22 | Map _$NavigaTumRoomFinderMapToJson(
23 | NavigaTumRoomFinderMap instance,
24 | ) => {
25 | 'id': instance.id,
26 | 'name': instance.name,
27 | 'file': instance.imageUrl,
28 | 'height': instance.height,
29 | 'width': instance.width,
30 | 'x': instance.x,
31 | 'y': instance.y,
32 | 'scale': instance.scale,
33 | };
34 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/search/navigatum_search_response.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/navigaTumComponent/model/search/navigatum_search_response_section.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'navigatum_search_response.g.dart';
5 |
6 | @JsonSerializable()
7 | class NavigaTumSearchResponse {
8 | final List sections;
9 |
10 | NavigaTumSearchResponse(this.sections);
11 |
12 | factory NavigaTumSearchResponse.fromJson(Map json) =>
13 | _$NavigaTumSearchResponseFromJson(json);
14 |
15 | Map toJson() => _$NavigaTumSearchResponseToJson(this);
16 | }
17 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/search/navigatum_search_response.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_search_response.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumSearchResponse _$NavigaTumSearchResponseFromJson(
10 | Map json,
11 | ) => NavigaTumSearchResponse(
12 | (json['sections'] as List)
13 | .map(
14 | (e) =>
15 | NavigaTumSearchResponseSection.fromJson(e as Map),
16 | )
17 | .toList(),
18 | );
19 |
20 | Map _$NavigaTumSearchResponseToJson(
21 | NavigaTumSearchResponse instance,
22 | ) => {'sections': instance.sections};
23 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/search/navigatum_search_response_section.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/navigaTumComponent/model/navigatum_navigation_entity.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'navigatum_search_response_section.g.dart';
5 |
6 | @JsonSerializable()
7 | class NavigaTumSearchResponseSection {
8 | @JsonKey(name: "facet")
9 | final String type;
10 | final List entries;
11 |
12 | NavigaTumSearchResponseSection(this.type, this.entries);
13 |
14 | factory NavigaTumSearchResponseSection.fromJson(Map json) =>
15 | _$NavigaTumSearchResponseSectionFromJson(json);
16 |
17 | Map toJson() => _$NavigaTumSearchResponseSectionToJson(this);
18 | }
19 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/model/search/navigatum_search_response_section.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'navigatum_search_response_section.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | NavigaTumSearchResponseSection _$NavigaTumSearchResponseSectionFromJson(
10 | Map json,
11 | ) => NavigaTumSearchResponseSection(
12 | json['facet'] as String,
13 | (json['entries'] as List)
14 | .map((e) => NavigaTumNavigationEntity.fromJson(e as Map))
15 | .toList(),
16 | );
17 |
18 | Map _$NavigaTumSearchResponseSectionToJson(
19 | NavigaTumSearchResponseSection instance,
20 | ) => {'facet': instance.type, 'entries': instance.entries};
21 |
--------------------------------------------------------------------------------
/lib/navigaTumComponent/services/navigatum_search_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/navigaTumApi/navigatum_api.dart';
2 | import 'package:campus_flutter/base/networking/apis/navigaTumApi/navigatum_api_endpoint.dart';
3 | import 'package:campus_flutter/base/networking/base/rest_client.dart';
4 | import 'package:campus_flutter/navigaTumComponent/model/search/navigatum_search_response.dart';
5 | import 'package:campus_flutter/main.dart';
6 |
7 | class NavigaTumSearchService {
8 | static Future<(DateTime?, NavigaTumSearchResponse)> fetchNavigaTumEntities(
9 | String query,
10 | bool forcedRefresh,
11 | ) async {
12 | RestClient restClient = getIt();
13 | final response = await restClient
14 | .get(
15 | NavigaTumApi(
16 | navigaTumApiEndpoint: NavigaTumApiEndpointSearch(query: query),
17 | ),
18 | NavigaTumSearchResponse.fromJson,
19 | forcedRefresh,
20 | );
21 |
22 | return (response.saved, response.data);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/onboardingComponent/model/confirm.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'confirm.g.dart';
4 |
5 | @JsonSerializable()
6 | class Confirm {
7 | @JsonKey(fromJson: bool.parse)
8 | final bool confirmed;
9 |
10 | Confirm({required this.confirmed});
11 |
12 | factory Confirm.fromJson(Map json) =>
13 | _$ConfirmFromJson(json);
14 |
15 | Map toJson() => _$ConfirmToJson(this);
16 | }
17 |
--------------------------------------------------------------------------------
/lib/onboardingComponent/model/confirm.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'confirm.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Confirm _$ConfirmFromJson(Map json) =>
10 | Confirm(confirmed: bool.parse(json['confirmed'] as String));
11 |
12 | Map _$ConfirmToJson(Confirm instance) => {
13 | 'confirmed': instance.confirmed,
14 | };
15 |
--------------------------------------------------------------------------------
/lib/onboardingComponent/model/token.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'token.g.dart';
4 |
5 | @JsonSerializable()
6 | class Token {
7 | @JsonKey(name: "token")
8 | final String content;
9 |
10 | Token({required this.content});
11 |
12 | factory Token.fromJson(Map json) => _$TokenFromJson(json);
13 |
14 | Map toJson() => _$TokenToJson(this);
15 | }
16 |
--------------------------------------------------------------------------------
/lib/onboardingComponent/model/token.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'token.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Token _$TokenFromJson(Map json) =>
10 | Token(content: json['token'] as String);
11 |
12 | Map _$TokenToJson(Token instance) => {
13 | 'token': instance.content,
14 | };
15 |
--------------------------------------------------------------------------------
/lib/onboardingComponent/views/location_permissions_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/onboardingComponent/viewModels/onboarding_viewmodel.dart';
2 | import 'package:campus_flutter/onboardingComponent/views/permission_view.dart';
3 | import 'package:easy_localization/easy_localization.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter_riverpod/flutter_riverpod.dart';
6 |
7 | class LocationPermissionView extends ConsumerWidget {
8 | const LocationPermissionView({super.key});
9 |
10 | @override
11 | Widget build(BuildContext context, WidgetRef ref) {
12 | return PermissionView(
13 | imagePath: "assets/images/location.png",
14 | title: context.tr("location"),
15 | description: context.tr("locationOnboarding"),
16 | onButtonPress:
17 | () => ref.read(onboardingViewModel).requestLocation(ref, context),
18 | );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/lib/personComponent/model/personDetails/contact_info.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'contact_info.g.dart';
4 |
5 | @JsonSerializable()
6 | class ContactInfo {
7 | @JsonKey(name: "telefon")
8 | final String? phone;
9 | @JsonKey(name: "fax")
10 | final String? fax;
11 | @JsonKey(name: "mobiltelefon")
12 | final String? mobilePhone;
13 | @JsonKey(name: "zusatz_info")
14 | final String? additionalInfo;
15 | @JsonKey(name: "www_homepage")
16 | final String? homepage;
17 |
18 | ContactInfo({
19 | this.phone,
20 | this.fax,
21 | this.mobilePhone,
22 | this.additionalInfo,
23 | this.homepage,
24 | });
25 |
26 | factory ContactInfo.fromJson(Map json) =>
27 | _$ContactInfoFromJson(json);
28 |
29 | Map toJson() => _$ContactInfoToJson(this);
30 | }
31 |
--------------------------------------------------------------------------------
/lib/personComponent/model/personDetails/contact_info.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'contact_info.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | ContactInfo _$ContactInfoFromJson(Map json) => ContactInfo(
10 | phone: json['telefon'] as String?,
11 | fax: json['fax'] as String?,
12 | mobilePhone: json['mobiltelefon'] as String?,
13 | additionalInfo: json['zusatz_info'] as String?,
14 | homepage: json['www_homepage'] as String?,
15 | );
16 |
17 | Map _$ContactInfoToJson(ContactInfo instance) =>
18 | {
19 | 'telefon': instance.phone,
20 | 'fax': instance.fax,
21 | 'mobiltelefon': instance.mobilePhone,
22 | 'zusatz_info': instance.additionalInfo,
23 | 'www_homepage': instance.homepage,
24 | };
25 |
--------------------------------------------------------------------------------
/lib/personComponent/model/personDetails/organisation.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'organisation.g.dart';
4 |
5 | @JsonSerializable()
6 | class Organisation {
7 | @JsonKey(name: "org")
8 | final String? name;
9 | @JsonKey(name: "kennung")
10 | final String? id;
11 | @JsonKey(name: "org_nr")
12 | final String? number;
13 | @JsonKey(name: "titel")
14 | final String? title;
15 | @JsonKey(name: "beschreibung")
16 | final String? description;
17 |
18 | Organisation({this.name, this.id, this.number, this.title, this.description});
19 |
20 | factory Organisation.fromJson(Map json) =>
21 | _$OrganisationFromJson(json);
22 |
23 | Map toJson() => _$OrganisationToJson(this);
24 | }
25 |
--------------------------------------------------------------------------------
/lib/personComponent/model/personDetails/organisation.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'organisation.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Organisation _$OrganisationFromJson(Map json) => Organisation(
10 | name: json['org'] as String?,
11 | id: json['kennung'] as String?,
12 | number: json['org_nr'] as String?,
13 | title: json['titel'] as String?,
14 | description: json['beschreibung'] as String?,
15 | );
16 |
17 | Map _$OrganisationToJson(Organisation instance) =>
18 | {
19 | 'org': instance.name,
20 | 'kennung': instance.id,
21 | 'org_nr': instance.number,
22 | 'titel': instance.title,
23 | 'beschreibung': instance.description,
24 | };
25 |
--------------------------------------------------------------------------------
/lib/personComponent/model/personDetails/phone_extension.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'phone_extension.g.dart';
4 |
5 | @JsonSerializable()
6 | class PhoneExtension {
7 | @JsonKey(name: "telefonnummer")
8 | final String? phoneNumber;
9 | @JsonKey(name: "tum_anlage_land")
10 | final String? countryCode;
11 | @JsonKey(name: "tum_anlage_ortsvorwahl")
12 | final String? areaCode;
13 | @JsonKey(name: "tum_anlage_nummer")
14 | final String? equipmentNumber;
15 | @JsonKey(name: "tum_nebenstelle")
16 | final String? branchNumber;
17 |
18 | PhoneExtension({
19 | this.phoneNumber,
20 | this.countryCode,
21 | this.areaCode,
22 | this.equipmentNumber,
23 | this.branchNumber,
24 | });
25 |
26 | factory PhoneExtension.fromJson(Map json) =>
27 | _$PhoneExtensionFromJson(json);
28 |
29 | Map toJson() => _$PhoneExtensionToJson(this);
30 | }
31 |
--------------------------------------------------------------------------------
/lib/personComponent/model/personDetails/phone_extension.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'phone_extension.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | PhoneExtension _$PhoneExtensionFromJson(Map json) =>
10 | PhoneExtension(
11 | phoneNumber: json['telefonnummer'] as String?,
12 | countryCode: json['tum_anlage_land'] as String?,
13 | areaCode: json['tum_anlage_ortsvorwahl'] as String?,
14 | equipmentNumber: json['tum_anlage_nummer'] as String?,
15 | branchNumber: json['tum_nebenstelle'] as String?,
16 | );
17 |
18 | Map _$PhoneExtensionToJson(PhoneExtension instance) =>
19 | {
20 | 'telefonnummer': instance.phoneNumber,
21 | 'tum_anlage_land': instance.countryCode,
22 | 'tum_anlage_ortsvorwahl': instance.areaCode,
23 | 'tum_anlage_nummer': instance.equipmentNumber,
24 | 'tum_nebenstelle': instance.branchNumber,
25 | };
26 |
--------------------------------------------------------------------------------
/lib/personComponent/model/personDetails/room.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'room.g.dart';
4 |
5 | @JsonSerializable()
6 | class Room {
7 | @JsonKey(name: "nummer")
8 | final String? number;
9 | @JsonKey(name: "gebaeudename")
10 | final String? buildingName;
11 | @JsonKey(name: "gebaeudenummer")
12 | final String? buildingNumber;
13 | @JsonKey(name: "stockwerkname")
14 | final String? floorName;
15 | @JsonKey(name: "stockwerknummer")
16 | final String? floorNumber;
17 | @JsonKey(name: "architekt")
18 | final String? id;
19 | @JsonKey(name: "ortsbeschreibung")
20 | final String? locationDescription;
21 | @JsonKey(name: "kurz")
22 | final String? shortLocationDescription;
23 | @JsonKey(name: "lang")
24 | final String? longLocationDescription;
25 |
26 | Room({
27 | this.number,
28 | this.buildingName,
29 | this.buildingNumber,
30 | this.floorName,
31 | this.floorNumber,
32 | this.id,
33 | this.locationDescription,
34 | this.shortLocationDescription,
35 | this.longLocationDescription,
36 | });
37 |
38 | factory Room.fromJson(Map json) => _$RoomFromJson(json);
39 |
40 | Map toJson() => _$RoomToJson(this);
41 | }
42 |
--------------------------------------------------------------------------------
/lib/personComponent/model/personSearch/person.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'person.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Person _$PersonFromJson(Map json) => Person(
10 | firstname: json['vorname'] as String,
11 | surname: json['familienname'] as String,
12 | title: json['titel'] as String?,
13 | nr: json['nr'] as String,
14 | obfuscatedID: json['obfuscated_id'] as String,
15 | );
16 |
17 | Map _$PersonToJson(Person instance) => {
18 | 'vorname': instance.firstname,
19 | 'familienname': instance.surname,
20 | 'titel': instance.title,
21 | 'nr': instance.nr,
22 | 'obfuscated_id': instance.obfuscatedID,
23 | };
24 |
25 | Persons _$PersonsFromJson(Map json) => Persons(
26 | persons:
27 | (json['row'] as List?)
28 | ?.map((e) => Person.fromJson(e as Map))
29 | .toList() ??
30 | [],
31 | );
32 |
33 | Map _$PersonsToJson(Persons instance) => {
34 | 'row': instance.persons,
35 | };
36 |
--------------------------------------------------------------------------------
/lib/personComponent/model/profile/tuition.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'tuition.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Tuition _$TuitionFromJson(Map json) => Tuition(
10 | amount: StringParser.stringToDouble(json['soll'] as String?),
11 | deadline: DateTime.parse(json['frist'] as String),
12 | semester: json['semester_bezeichnung'] as String,
13 | semesterID: json['semester_id'] as String,
14 | );
15 |
16 | Map _$TuitionToJson(Tuition instance) => {
17 | 'soll': instance.amount,
18 | 'frist': instance.deadline.toIso8601String(),
19 | 'semester_bezeichnung': instance.semester,
20 | 'semester_id': instance.semesterID,
21 | };
22 |
23 | Tuitions _$TuitionsFromJson(Map json) =>
24 | Tuitions(tuition: Tuitions._tuitionFromJson(json['row']));
25 |
26 | Map _$TuitionsToJson(Tuitions instance) => {
27 | 'row': instance.tuition,
28 | };
29 |
--------------------------------------------------------------------------------
/lib/personComponent/services/person_details_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/tumOnlineApi/tum_online_api.dart';
2 | import 'package:campus_flutter/base/networking/apis/tumOnlineApi/tum_online_api_exception.dart';
3 | import 'package:campus_flutter/base/networking/apis/tumOnlineApi/tum_online_api_endpoint.dart';
4 | import 'package:campus_flutter/base/networking/base/rest_client.dart';
5 | import 'package:campus_flutter/main.dart';
6 | import 'package:campus_flutter/personComponent/model/personDetails/person_details.dart';
7 |
8 | class PersonDetailsService {
9 | static Future<(DateTime?, PersonDetails)> fetchPersonDetails(
10 | bool forcedRefresh,
11 | String identNumber,
12 | ) async {
13 | RestClient restClient = getIt();
14 | final response = await restClient.getWithException<
15 | PersonDetailsData,
16 | TumOnlineApi,
17 | TumOnlineApiException
18 | >(
19 | TumOnlineApi(TumOnlineEndpointPersonDetails(identNumber: identNumber)),
20 | PersonDetailsData.fromJson,
21 | TumOnlineApiException.fromJson,
22 | forcedRefresh,
23 | );
24 | return (response.saved, response.data.person);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/personComponent/services/person_search_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/base/networking/apis/tumOnlineApi/tum_online_api.dart';
2 | import 'package:campus_flutter/base/networking/apis/tumOnlineApi/tum_online_api_exception.dart';
3 | import 'package:campus_flutter/base/networking/apis/tumOnlineApi/tum_online_api_endpoint.dart';
4 | import 'package:campus_flutter/base/networking/base/rest_client.dart';
5 | import 'package:campus_flutter/personComponent/model/personSearch/person.dart';
6 | import 'package:campus_flutter/main.dart';
7 |
8 | class PersonSearchService {
9 | static Future<(DateTime?, List)> fetchPersons(
10 | String query,
11 | bool forcedRefresh,
12 | ) async {
13 | RestClient restClient = getIt();
14 | final response = await restClient
15 | .getWithException(
16 | TumOnlineApi(TumOnlineEndpointPersonSearch(search: query)),
17 | Persons.fromJson,
18 | TumOnlineApiException.fromJson,
19 | forcedRefresh,
20 | );
21 |
22 | return (response.saved, response.data.persons);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/personComponent/viewModel/profile_viewmodel.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/personComponent/model/profile/profile.dart';
2 | import 'package:campus_flutter/personComponent/model/profile/tuition.dart';
3 | import 'package:campus_flutter/personComponent/services/profile_service.dart';
4 | import 'package:flutter_riverpod/flutter_riverpod.dart';
5 | import 'package:rxdart/rxdart.dart';
6 |
7 | final profileViewModel = Provider((ref) => ProfileViewModel());
8 |
9 | class ProfileViewModel {
10 | BehaviorSubject profile = BehaviorSubject.seeded(null);
11 | BehaviorSubject tuition = BehaviorSubject.seeded(null);
12 | final BehaviorSubject lastFetched = BehaviorSubject.seeded(null);
13 |
14 | Future fetch(bool forcedRefresh) async {
15 | ProfileService.fetchProfile(forcedRefresh).then((response) {
16 | lastFetched.add(response.$1);
17 | profile.add(response.$2);
18 | ProfileService.fetchTuition(
19 | forcedRefresh,
20 | response.$2.personGroup ?? "",
21 | response.$2.id ?? "",
22 | ).then(
23 | (response) => tuition.add(response.$2),
24 | onError: (error) => tuition.addError(error),
25 | );
26 | }, onError: (error) => profile.addError(error));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/placesComponent/model/cafeterias/cafeteria_menu.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/placesComponent/model/cafeterias/mensa_menu.dart';
2 |
3 | /// local class
4 | class CafeteriaMenu {
5 | final DateTime date;
6 | final List categories;
7 |
8 | CafeteriaMenu({required this.date, required this.categories});
9 | }
10 |
--------------------------------------------------------------------------------
/lib/placesComponent/model/cafeterias/dish.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'dish.g.dart';
4 |
5 | @JsonSerializable()
6 | class Dish {
7 | final String name;
8 | final Map prices;
9 | final List labels;
10 | @JsonKey(name: "dish_type")
11 | final String dishType;
12 |
13 | Dish({
14 | required this.name,
15 | required this.prices,
16 | required this.labels,
17 | required this.dishType,
18 | });
19 |
20 | factory Dish.fromJson(Map json) => _$DishFromJson(json);
21 |
22 | Map toJson() => _$DishToJson(this);
23 | }
24 |
25 | @JsonSerializable()
26 | class Price {
27 | @JsonKey(name: "base_price")
28 | final double? basePrice;
29 | @JsonKey(name: "price_per_unit")
30 | final double? unitPrice;
31 | final String? unit;
32 |
33 | Price({this.basePrice, this.unitPrice, this.unit});
34 |
35 | factory Price.fromJson(Map json) => _$PriceFromJson(json);
36 |
37 | Map toJson() => _$PriceToJson(this);
38 | }
39 |
--------------------------------------------------------------------------------
/lib/placesComponent/model/cafeterias/meal_plan.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/placesComponent/model/cafeterias/mensa_menu.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'meal_plan.g.dart';
5 |
6 | @JsonSerializable()
7 | class MealPlan {
8 | @JsonKey(name: "number")
9 | final int week;
10 | final int year;
11 | final List days;
12 |
13 | MealPlan({required this.week, required this.year, required this.days});
14 |
15 | factory MealPlan.fromJson(Map json) =>
16 | _$MealPlanFromJson(json);
17 |
18 | Map toJson() => _$MealPlanToJson(this);
19 | }
20 |
--------------------------------------------------------------------------------
/lib/placesComponent/model/cafeterias/meal_plan.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'meal_plan.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | MealPlan _$MealPlanFromJson(Map json) => MealPlan(
10 | week: (json['number'] as num).toInt(),
11 | year: (json['year'] as num).toInt(),
12 | days:
13 | (json['days'] as List)
14 | .map((e) => MensaMenu.fromJson(e as Map))
15 | .toList(),
16 | );
17 |
18 | Map _$MealPlanToJson(MealPlan instance) => {
19 | 'number': instance.week,
20 | 'year': instance.year,
21 | 'days': instance.days,
22 | };
23 |
--------------------------------------------------------------------------------
/lib/placesComponent/model/cafeterias/mensa_menu.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/placesComponent/model/cafeterias/dish.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'mensa_menu.g.dart';
5 |
6 | @JsonSerializable()
7 | class MensaMenu {
8 | final DateTime date;
9 | final List dishes;
10 |
11 | MensaMenu({required this.date, required this.dishes});
12 |
13 | factory MensaMenu.fromJson(Map json) =>
14 | _$MensaMenuFromJson(json);
15 |
16 | Map toJson() => _$MensaMenuToJson(this);
17 | }
18 |
19 | @JsonSerializable()
20 | class MenuCategory {
21 | final String name;
22 | final List dishes;
23 |
24 | MenuCategory({required this.name, required this.dishes});
25 |
26 | factory MenuCategory.fromJson(Map json) =>
27 | _$MenuCategoryFromJson(json);
28 |
29 | Map toJson() => _$MenuCategoryToJson(this);
30 | }
31 |
--------------------------------------------------------------------------------
/lib/placesComponent/model/cafeterias/mensa_menu.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'mensa_menu.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | MensaMenu _$MensaMenuFromJson(Map json) => MensaMenu(
10 | date: DateTime.parse(json['date'] as String),
11 | dishes:
12 | (json['dishes'] as List)
13 | .map((e) => Dish.fromJson(e as Map))
14 | .toList(),
15 | );
16 |
17 | Map _$MensaMenuToJson(MensaMenu instance) => {
18 | 'date': instance.date.toIso8601String(),
19 | 'dishes': instance.dishes,
20 | };
21 |
22 | MenuCategory _$MenuCategoryFromJson(Map json) => MenuCategory(
23 | name: json['name'] as String,
24 | dishes:
25 | (json['dishes'] as List)
26 | .map((e) => Dish.fromJson(e as Map))
27 | .toList(),
28 | );
29 |
30 | Map _$MenuCategoryToJson(MenuCategory instance) =>
31 | {'name': instance.name, 'dishes': instance.dishes};
32 |
--------------------------------------------------------------------------------
/lib/placesComponent/model/cafeterias/opening_hours.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'opening_hours.g.dart';
4 |
5 | @JsonSerializable()
6 | class OpeningHours {
7 | final OpeningHour? mon;
8 | final OpeningHour? tue;
9 | final OpeningHour? wed;
10 | final OpeningHour? thu;
11 | final OpeningHour? fri;
12 |
13 | OpeningHours({this.mon, this.tue, this.wed, this.thu, this.fri});
14 |
15 | factory OpeningHours.fromJson(Map json) =>
16 | _$OpeningHoursFromJson(json);
17 |
18 | Map toJson() => _$OpeningHoursToJson(this);
19 | }
20 |
21 | @JsonSerializable()
22 | class OpeningHour {
23 | final String start;
24 | final String end;
25 |
26 | OpeningHour({required this.start, required this.end});
27 |
28 | factory OpeningHour.fromJson(Map json) =>
29 | _$OpeningHourFromJson(json);
30 |
31 | Map toJson() => _$OpeningHourToJson(this);
32 | }
33 |
--------------------------------------------------------------------------------
/lib/placesComponent/model/studyRooms/study_room_attribute.dart:
--------------------------------------------------------------------------------
1 | import 'package:campus_flutter/searchComponent/model/comparison_token.dart';
2 | import 'package:campus_flutter/searchComponent/protocols/searchable.dart';
3 | import 'package:json_annotation/json_annotation.dart';
4 |
5 | part 'study_room_attribute.g.dart';
6 |
7 | @JsonSerializable()
8 | class StudyRoomAttribute extends Searchable {
9 | final String? detail;
10 | final String? name;
11 |
12 | @override
13 | @JsonKey(includeFromJson: false, includeToJson: false)
14 | List get comparisonTokens => [
15 | ComparisonToken(value: detail ?? ""),
16 | ComparisonToken(value: name ?? ""),
17 | ];
18 |
19 | StudyRoomAttribute({this.detail, this.name});
20 |
21 | factory StudyRoomAttribute.fromJson(Map json) =>
22 | _$StudyRoomAttributeFromJson(json);
23 |
24 | Map