├── .gitignore ├── LICENSE ├── README.md ├── frontend ├── BirdAtlas.Android │ ├── Assets │ │ ├── AboutAssets.txt │ │ ├── Montserrat-Light.ttf │ │ ├── Montserrat-Medium.ttf │ │ ├── Montserrat-Regular.ttf │ │ ├── Montserrat-SemiBold.ttf │ │ └── materialdesignicons-webfont.ttf │ ├── BirdAtlas.Android.csproj │ ├── Framework │ │ └── DeviceInfo.cs │ ├── MainActivity.cs │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ └── Resources │ │ ├── AboutResources.txt │ │ ├── Resource.designer.cs │ │ ├── layout │ │ ├── Tabbar.axml │ │ └── Toolbar.axml │ │ ├── mipmap-anydpi-v26 │ │ ├── icon.xml │ │ └── icon_round.xml │ │ ├── mipmap-hdpi │ │ ├── icon.png │ │ └── launcher_foreground.png │ │ ├── mipmap-mdpi │ │ ├── icon.png │ │ └── launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ ├── icon.png │ │ └── launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ ├── icon.png │ │ └── launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ ├── icon.png │ │ └── launcher_foreground.png │ │ └── values │ │ ├── colors.xml │ │ └── styles.xml ├── BirdAtlas.iOS │ ├── AppDelegate.cs │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon1024.png │ │ │ ├── Icon120.png │ │ │ ├── Icon152.png │ │ │ ├── Icon167.png │ │ │ ├── Icon180.png │ │ │ ├── Icon20.png │ │ │ ├── Icon29.png │ │ │ ├── Icon40.png │ │ │ ├── Icon58.png │ │ │ ├── Icon60.png │ │ │ ├── Icon76.png │ │ │ ├── Icon80.png │ │ │ └── Icon87.png │ ├── BirdAtlas.iOS.csproj │ ├── Entitlements.plist │ ├── Framework │ │ └── DeviceInfo.cs │ ├── Info.plist │ ├── Main.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── Default-568h@2x.png │ │ ├── Default-Portrait.png │ │ ├── Default-Portrait@2x.png │ │ ├── Default.png │ │ ├── Default@2x.png │ │ ├── LaunchScreen.storyboard │ │ ├── Montserrat-Light.ttf │ │ ├── Montserrat-Medium.ttf │ │ ├── Montserrat-Regular.ttf │ │ ├── Montserrat-SemiBold.ttf │ │ ├── ic_bookmarks.png │ │ ├── ic_bookmarks@2x.png │ │ ├── ic_bookmarks@3x.png │ │ ├── ic_discover.png │ │ ├── ic_discover@2x.png │ │ ├── ic_discover@3x.png │ │ ├── ic_search.png │ │ ├── ic_search@2x.png │ │ ├── ic_search@3x.png │ │ └── materialdesignicons-webfont.ttf │ └── mono_crash.115869eaf6.0.json ├── BirdAtlas.sln └── BirdAtlas │ ├── App.xaml │ ├── App.xaml.cs │ ├── Behaviors │ └── EntranceBehavior.cs │ ├── BirdAtlas.csproj │ ├── Converters │ └── HabitatTypeToColorConverter.cs │ ├── Extensions │ └── IEnumerableExtensions.cs │ ├── Framework │ └── IDeviceInfo.cs │ ├── Models │ ├── Enums.cs │ ├── Habitat.cs │ ├── IconFont.cs │ ├── Nearby.cs │ └── Story.cs │ ├── Services │ ├── BirdAtlasMockAPI.cs │ └── IBirdAtlasAPI.cs │ ├── ViewModels │ ├── BaseViewModel.cs │ ├── BookmarkViewModel.cs │ ├── DiscoverViewModel.cs │ ├── SearchViewModel.cs │ ├── SettingsViewModel.cs │ ├── StartViewModel.cs │ ├── StoryDetailViewModel.cs │ └── StoryOverviewViewModel.cs │ ├── Views │ ├── BasePage.xaml │ ├── BasePage.xaml.cs │ ├── SettingsPage.xaml │ ├── SettingsPage.xaml.cs │ ├── StartPage.xaml │ ├── StartPage.xaml.cs │ ├── StoryDetailPage.xaml │ ├── StoryDetailPage.xaml.cs │ ├── StoryOverviewPage.xaml │ ├── StoryOverviewPage.xaml.cs │ └── TabViews │ │ ├── BookmarkTabView.xaml │ │ ├── BookmarkTabView.xaml.cs │ │ ├── DiscoverTabView.xaml │ │ ├── DiscoverTabView.xaml.cs │ │ ├── SearchTabView.xaml │ │ └── SearchTabView.xaml.cs │ └── XamlResources │ ├── DataTemplates.xaml │ ├── DataTemplates.xaml.cs │ ├── Styles.xaml │ └── Styles.xaml.cs ├── frontend_flutter ├── .gitignore ├── .metadata ├── .vscode │ ├── launch.json │ └── settings.json ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── frontend_flutter │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── fonts │ ├── Montserrat-Light.ttf │ ├── Montserrat-Medium.ttf │ ├── Montserrat-Regular.ttf │ └── Montserrat-SemiBold.ttf ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── 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-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── main.dart │ ├── main │ │ ├── mainPage.dart │ │ └── tabs │ │ │ ├── bookmarkTab.dart │ │ │ ├── discoverTab.dart │ │ │ ├── searchTab.dart │ │ │ └── tabAppBar.dart │ ├── models.dart │ ├── services │ │ ├── birdatlasAPIInterface.dart │ │ └── birdatlasAPIMocked.dart │ └── styles.dart ├── pubspec.lock └── pubspec.yaml └── frontend_maui ├── BirdAtlasMaui.sln └── BirdAtlasMaui ├── App.xaml ├── App.xaml.cs ├── BirdAtlasMaui.csproj ├── Client └── RestServiceFactory.cs ├── Constants └── Constants.cs ├── Models ├── Bird.cs ├── Habitat.cs ├── HabitatType.cs └── Story.cs ├── Platforms ├── Android │ ├── AndroidManifest.xml │ ├── MainActivity.cs │ ├── MainApplication.cs │ └── Resources │ │ └── values │ │ ├── colors.xml │ │ └── styles.xml ├── MacCatalyst │ ├── AppDelegate.cs │ ├── Info.plist │ └── Program.cs └── iOS │ ├── AppDelegate.cs │ ├── Info.plist │ ├── Program.cs │ └── Resources │ └── LaunchScreen.xib ├── Resources ├── Fonts │ └── OpenSans-Regular.ttf ├── Images │ └── dotnet_bot.svg ├── appicon.svg └── appiconfg.svg ├── Services ├── API │ ├── IBirdApi.cs │ ├── IHabitatApi.cs │ └── IStoryApi.cs ├── BirdService.cs ├── HabitatService.cs └── StoryService.cs ├── Startup.cs ├── ViewModels ├── BaseViewModel.cs ├── BirdViewModel.cs ├── MainViewModel.cs └── StoriesViewModel.cs └── Views ├── BirdPage.xaml ├── BirdPage.xaml.cs ├── MainPage.xaml ├── MainPage.xaml.cs ├── StoriesPage.xaml └── StoriesPage.xaml.cs /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BirdAtlas 2 | 3 | ## Design 4 | Based upon [Dribbble project](https://dribbble.com/shots/5442850-Bird-Atlas-App) created by [Monika Michalczyk](https://dribbble.com/michalczyk) 5 | 6 | ![BirdAtlas](https://cdn.dribbble.com/users/1168539/screenshots/5442850/frame__2_.png) -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Assets/Montserrat-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Assets/Montserrat-Light.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Assets/Montserrat-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Assets/Montserrat-Medium.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Assets/Montserrat-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Assets/Montserrat-Regular.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Assets/Montserrat-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Assets/Montserrat-SemiBold.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Assets/materialdesignicons-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Assets/materialdesignicons-webfont.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Framework/DeviceInfo.cs: -------------------------------------------------------------------------------- 1 | using BirdAtlas.Droid.Framework; 2 | using BirdAtlas.Framework; 3 | using Xamarin.Forms; 4 | 5 | [assembly: Dependency(typeof(DeviceInfo))] 6 | namespace BirdAtlas.Droid.Framework 7 | { 8 | public class DeviceInfo : IDeviceInfo 9 | { 10 | public float StatusbarHeight => 0; 11 | } 12 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | using Sharpnado.HorizontalListView.Droid; 5 | using Xamarin.Forms; 6 | 7 | namespace BirdAtlas.Droid 8 | { 9 | [Activity(Label = "BirdAtlas", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 10 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 11 | { 12 | protected override void OnCreate(Bundle savedInstanceState) 13 | { 14 | TabLayoutResource = Resource.Layout.Tabbar; 15 | ToolbarResource = Resource.Layout.Toolbar; 16 | 17 | base.OnCreate(savedInstanceState); 18 | Forms.SetFlags("CollectionView_Experimental"); 19 | global::Xamarin.Forms.Forms.Init(this, savedInstanceState); 20 | 21 | SharpnadoInitializer.Initialize(enableInternalLogger: true, enableInternalDebugLogger: true); 22 | 23 | LoadApplication(new App()); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("BirdAtlas.Android")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("BirdAtlas.Android")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | 32 | // Add some common permissions, these can be removed if not needed 33 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)] 34 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] 35 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable-hdpi/ 12 | icon.png 13 | 14 | drawable-ldpi/ 15 | icon.png 16 | 17 | drawable-mdpi/ 18 | icon.png 19 | 20 | layout/ 21 | main.xml 22 | 23 | values/ 24 | strings.xml 25 | 26 | In order to get the build system to recognize Android resources, set the build action to 27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 28 | instead operate on resource IDs. When you compile an Android application that uses resources, 29 | the build system will package the resources for distribution and generate a class called 30 | "Resource" that contains the tokens for each one of the resources included. For example, 31 | for the above Resources layout, this is what the Resource class would expose: 32 | 33 | public class Resource { 34 | public class drawable { 35 | public const int icon = 0x123; 36 | } 37 | 38 | public class layout { 39 | public const int main = 0x456; 40 | } 41 | 42 | public class strings { 43 | public const int first_string = 0xabc; 44 | public const int second_string = 0xbcd; 45 | } 46 | } 47 | 48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main 49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first 50 | string in the dictionary file values/strings.xml. 51 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/layout/Tabbar.axml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/layout/Toolbar.axml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-anydpi-v26/icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-anydpi-v26/icon_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-hdpi/icon.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-hdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-hdpi/launcher_foreground.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-mdpi/icon.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-mdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-mdpi/launcher_foreground.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-xhdpi/icon.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-xhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-xhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-xxhdpi/icon.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-xxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-xxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-xxxhdpi/icon.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #3F51B5 5 | #303F9F 6 | #FF4081 7 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.Android/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 24 | 27 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using Sharpnado.HorizontalListView; 3 | using UIKit; 4 | using Xamarin.Forms; 5 | 6 | namespace BirdAtlas.iOS 7 | { 8 | // The UIApplicationDelegate for the application. This class is responsible for launching the 9 | // User Interface of the application, as well as listening (and optionally responding) to 10 | // application events from iOS. 11 | [Register("AppDelegate")] 12 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 13 | { 14 | // 15 | // This method is invoked when the application has loaded and is ready to run. In this 16 | // method you should instantiate the window, load the UI into it and then make the window 17 | // visible. 18 | // 19 | // You have 17 seconds to return from this method, or iOS will terminate your application. 20 | // 21 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 22 | { 23 | Forms.SetFlags("CollectionView_Experimental"); 24 | global::Xamarin.Forms.Forms.Init(); 25 | 26 | Sharpnado.HorizontalListView.iOS.SharpnadoInitializer.Initialize(); 27 | Sharpnado.Tabs.iOS.Preserver.Preserve(); 28 | 29 | LoadApplication(new App()); 30 | 31 | return base.FinishedLaunching(app, options); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "scale": "2x", 5 | "size": "20x20", 6 | "idiom": "iphone", 7 | "filename": "Icon40.png" 8 | }, 9 | { 10 | "scale": "3x", 11 | "size": "20x20", 12 | "idiom": "iphone", 13 | "filename": "Icon60.png" 14 | }, 15 | { 16 | "scale": "2x", 17 | "size": "29x29", 18 | "idiom": "iphone", 19 | "filename": "Icon58.png" 20 | }, 21 | { 22 | "scale": "3x", 23 | "size": "29x29", 24 | "idiom": "iphone", 25 | "filename": "Icon87.png" 26 | }, 27 | { 28 | "scale": "2x", 29 | "size": "40x40", 30 | "idiom": "iphone", 31 | "filename": "Icon80.png" 32 | }, 33 | { 34 | "scale": "3x", 35 | "size": "40x40", 36 | "idiom": "iphone", 37 | "filename": "Icon120.png" 38 | }, 39 | { 40 | "scale": "2x", 41 | "size": "60x60", 42 | "idiom": "iphone", 43 | "filename": "Icon120.png" 44 | }, 45 | { 46 | "scale": "3x", 47 | "size": "60x60", 48 | "idiom": "iphone", 49 | "filename": "Icon180.png" 50 | }, 51 | { 52 | "scale": "1x", 53 | "size": "20x20", 54 | "idiom": "ipad", 55 | "filename": "Icon20.png" 56 | }, 57 | { 58 | "scale": "2x", 59 | "size": "20x20", 60 | "idiom": "ipad", 61 | "filename": "Icon40.png" 62 | }, 63 | { 64 | "scale": "1x", 65 | "size": "29x29", 66 | "idiom": "ipad", 67 | "filename": "Icon29.png" 68 | }, 69 | { 70 | "scale": "2x", 71 | "size": "29x29", 72 | "idiom": "ipad", 73 | "filename": "Icon58.png" 74 | }, 75 | { 76 | "scale": "1x", 77 | "size": "40x40", 78 | "idiom": "ipad", 79 | "filename": "Icon40.png" 80 | }, 81 | { 82 | "scale": "2x", 83 | "size": "40x40", 84 | "idiom": "ipad", 85 | "filename": "Icon80.png" 86 | }, 87 | { 88 | "scale": "1x", 89 | "size": "76x76", 90 | "idiom": "ipad", 91 | "filename": "Icon76.png" 92 | }, 93 | { 94 | "scale": "2x", 95 | "size": "76x76", 96 | "idiom": "ipad", 97 | "filename": "Icon152.png" 98 | }, 99 | { 100 | "scale": "2x", 101 | "size": "83.5x83.5", 102 | "idiom": "ipad", 103 | "filename": "Icon167.png" 104 | }, 105 | { 106 | "scale": "1x", 107 | "size": "1024x1024", 108 | "idiom": "ios-marketing", 109 | "filename": "Icon1024.png" 110 | } 111 | ], 112 | "properties": {}, 113 | "info": { 114 | "version": 1, 115 | "author": "xcode" 116 | } 117 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Framework/DeviceInfo.cs: -------------------------------------------------------------------------------- 1 | using BirdAtlas.Framework; 2 | using BirdAtlas.iOS.Framework; 3 | using UIKit; 4 | using Xamarin.Forms; 5 | 6 | [assembly: Dependency(typeof(DeviceInfo))] 7 | namespace BirdAtlas.iOS.Framework 8 | { 9 | public class DeviceInfo : IDeviceInfo 10 | { 11 | public float StatusbarHeight => (float)UIApplication.SharedApplication.StatusBarFrame.Size.Height; 12 | } 13 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIDeviceFamily 6 | 7 | 1 8 | 2 9 | 10 | UISupportedInterfaceOrientations 11 | 12 | UIInterfaceOrientationPortrait 13 | UIInterfaceOrientationLandscapeLeft 14 | UIInterfaceOrientationLandscapeRight 15 | 16 | UISupportedInterfaceOrientations~ipad 17 | 18 | UIInterfaceOrientationPortrait 19 | UIInterfaceOrientationPortraitUpsideDown 20 | UIInterfaceOrientationLandscapeLeft 21 | UIInterfaceOrientationLandscapeRight 22 | 23 | MinimumOSVersion 24 | 8.0 25 | CFBundleDisplayName 26 | BirdAtlas 27 | CFBundleIdentifier 28 | com.companyname.BirdAtlas 29 | CFBundleVersion 30 | 1.0 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | CFBundleName 34 | BirdAtlas 35 | XSAppIconAssets 36 | Assets.xcassets/AppIcon.appiconset 37 | UIAppFonts 38 | 39 | materialdesignicons-webfont.ttf 40 | Montserrat-Medium.ttf 41 | Montserrat-SemiBold.ttf 42 | Montserrat-Regular.ttf 43 | Montserrat-Light.ttf 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace BirdAtlas.iOS 9 | { 10 | public class Application 11 | { 12 | // This is the main entry point of the application. 13 | static void Main(string[] args) 14 | { 15 | // if you want to use a different Application Delegate class from "AppDelegate" 16 | // you can specify it here. 17 | UIApplication.Main(args, null, "AppDelegate"); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("BirdAtlas.iOS")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("BirdAtlas.iOS")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Default-568h@2x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Default-Portrait.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Default-Portrait@2x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Default.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Default@2x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Montserrat-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Montserrat-Light.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Montserrat-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Montserrat-Medium.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Montserrat-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Montserrat-Regular.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/Montserrat-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/Montserrat-SemiBold.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_bookmarks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_bookmarks.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_bookmarks@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_bookmarks@2x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_bookmarks@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_bookmarks@3x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_discover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_discover.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_discover@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_discover@2x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_discover@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_discover@3x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_search.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_search@2x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/ic_search@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/ic_search@3x.png -------------------------------------------------------------------------------- /frontend/BirdAtlas.iOS/Resources/materialdesignicons-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AppCreativity/BirdAtlas/7b4bb9ad6aecad58e660381a38adcd32af66d797/frontend/BirdAtlas.iOS/Resources/materialdesignicons-webfont.ttf -------------------------------------------------------------------------------- /frontend/BirdAtlas.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdAtlas.Android", "BirdAtlas.Android\BirdAtlas.Android.csproj", "{59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdAtlas.iOS", "BirdAtlas.iOS\BirdAtlas.iOS.csproj", "{1866B926-D5BE-4248-9C4C-274B8F098D54}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdAtlas", "BirdAtlas\BirdAtlas.csproj", "{0100D27D-7213-4971-807D-130F269A7D67}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | Debug|iPhoneSimulator = Debug|iPhoneSimulator 15 | Release|iPhoneSimulator = Release|iPhoneSimulator 16 | Debug|iPhone = Debug|iPhone 17 | Release|iPhone = Release|iPhone 18 | Ad-Hoc|iPhone = Ad-Hoc|iPhone 19 | AppStore|iPhone = AppStore|iPhone 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 27 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 28 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 29 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 30 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Debug|iPhone.ActiveCfg = Debug|Any CPU 31 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Debug|iPhone.Build.0 = Debug|Any CPU 32 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Release|iPhone.ActiveCfg = Release|Any CPU 33 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Release|iPhone.Build.0 = Release|Any CPU 34 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU 35 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU 36 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.AppStore|iPhone.ActiveCfg = Debug|Any CPU 37 | {59AE4C14-86B8-4C59-BBC2-C5F70ACF15CF}.AppStore|iPhone.Build.0 = Debug|Any CPU 38 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator 39 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator 40 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator 41 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Release|Any CPU.Build.0 = Release|iPhoneSimulator 42 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator 43 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator 44 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator 45 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator 46 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Debug|iPhone.ActiveCfg = Debug|iPhone 47 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Debug|iPhone.Build.0 = Debug|iPhone 48 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Release|iPhone.ActiveCfg = Release|iPhone 49 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Release|iPhone.Build.0 = Release|iPhone 50 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone 51 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone 52 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.AppStore|iPhone.ActiveCfg = AppStore|iPhone 53 | {1866B926-D5BE-4248-9C4C-274B8F098D54}.AppStore|iPhone.Build.0 = AppStore|iPhone 54 | {0100D27D-7213-4971-807D-130F269A7D67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {0100D27D-7213-4971-807D-130F269A7D67}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {0100D27D-7213-4971-807D-130F269A7D67}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {0100D27D-7213-4971-807D-130F269A7D67}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {0100D27D-7213-4971-807D-130F269A7D67}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 59 | {0100D27D-7213-4971-807D-130F269A7D67}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 60 | {0100D27D-7213-4971-807D-130F269A7D67}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 61 | {0100D27D-7213-4971-807D-130F269A7D67}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 62 | {0100D27D-7213-4971-807D-130F269A7D67}.Debug|iPhone.ActiveCfg = Debug|Any CPU 63 | {0100D27D-7213-4971-807D-130F269A7D67}.Debug|iPhone.Build.0 = Debug|Any CPU 64 | {0100D27D-7213-4971-807D-130F269A7D67}.Release|iPhone.ActiveCfg = Release|Any CPU 65 | {0100D27D-7213-4971-807D-130F269A7D67}.Release|iPhone.Build.0 = Release|Any CPU 66 | {0100D27D-7213-4971-807D-130F269A7D67}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU 67 | {0100D27D-7213-4971-807D-130F269A7D67}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU 68 | {0100D27D-7213-4971-807D-130F269A7D67}.AppStore|iPhone.ActiveCfg = Debug|Any CPU 69 | {0100D27D-7213-4971-807D-130F269A7D67}.AppStore|iPhone.Build.0 = Debug|Any CPU 70 | EndGlobalSection 71 | EndGlobal 72 | -------------------------------------------------------------------------------- /frontend/BirdAtlas/App.xaml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /frontend/BirdAtlas/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using BirdAtlas.Views; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | using Prism; 5 | using Prism.DryIoc; 6 | using Prism.Ioc; 7 | using BirdAtlas.ViewModels; 8 | using BirdAtlas.Services; 9 | 10 | [assembly: XamlCompilation(XamlCompilationOptions.Compile)] 11 | namespace BirdAtlas 12 | { 13 | public partial class App : PrismApplication 14 | { 15 | public App() : this(null) { } 16 | 17 | public App(IPlatformInitializer platformInitializer) : base(platformInitializer) 18 | { 19 | } 20 | 21 | protected override async void OnInitialized() 22 | { 23 | InitializeComponent(); 24 | 25 | Sharpnado.Tabs.Initializer.Initialize(false, false); 26 | Sharpnado.Shades.Initializer.Initialize(false); 27 | Sharpnado.HorizontalListView.Initializer.Initialize(false, false); 28 | 29 | await NavigationService.NavigateAsync("NavigationPage/StartPage"); 30 | } 31 | 32 | protected override void RegisterTypes(IContainerRegistry containerRegistry) 33 | { 34 | containerRegistry.RegisterSingleton(); 35 | 36 | containerRegistry.RegisterForNavigation(); 37 | containerRegistry.RegisterForNavigation(); 38 | containerRegistry.RegisterForNavigation(); 39 | containerRegistry.RegisterForNavigation(); 40 | containerRegistry.RegisterForNavigation(); 41 | containerRegistry.RegisterForNavigation(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Behaviors/EntranceBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Xamarin.Forms; 4 | 5 | namespace BirdAtlas.Behaviors 6 | { 7 | public class EntranceTransition : Behavior 8 | { 9 | const int Delay = 100; 10 | const int TranslateFrom = 6; 11 | 12 | private VisualElement _associatedObject; 13 | 14 | public static readonly BindableProperty DurationProperty = 15 | BindableProperty.Create(nameof(Duration), typeof(string), typeof(EntranceTransition), "500", 16 | BindingMode.TwoWay, null); 17 | 18 | public string Duration 19 | { 20 | get { return (string)GetValue(DurationProperty); } 21 | set { SetValue(DurationProperty, value); } 22 | } 23 | 24 | protected override void OnAttachedTo(VisualElement bindable) 25 | { 26 | base.OnAttachedTo(bindable); 27 | _associatedObject = bindable; 28 | _associatedObject.PropertyChanged += OnPropertyChanged; 29 | } 30 | 31 | protected override void OnDetachingFrom(VisualElement bindable) 32 | { 33 | StopAnimation(); 34 | _associatedObject.PropertyChanged -= OnPropertyChanged; 35 | _associatedObject = null; 36 | base.OnDetachingFrom(bindable); 37 | } 38 | 39 | async void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 40 | { 41 | if (e.PropertyName == "Renderer") 42 | await StartAnimationAsync(); 43 | } 44 | 45 | void SetInitialTransitionState() 46 | { 47 | SetInitialTransitionState(_associatedObject); 48 | } 49 | 50 | void SetInitialTransitionState(VisualElement element) 51 | { 52 | element.Opacity = 0; 53 | element.TranslationX = _associatedObject.TranslationX + TranslateFrom; 54 | element.TranslationY = _associatedObject.TranslationY + TranslateFrom; 55 | } 56 | 57 | void StopAnimation() 58 | { 59 | ViewExtensions.CancelAnimations(_associatedObject); 60 | } 61 | 62 | async Task StartAnimationAsync() 63 | { 64 | StopAnimation(); 65 | SetInitialTransitionState(); 66 | 67 | //if (!HasParentEntranceTransition(_associatedObject)) 68 | await AnimateItemAsync(_associatedObject); 69 | } 70 | 71 | async Task AnimateItemAsync(VisualElement element) 72 | { 73 | await Task.Delay(Delay); 74 | 75 | var parentAnimation = new Animation(); 76 | 77 | var translateXAnimation = new Animation(v => element.TranslationX = v, element.TranslationX, 0, Easing.SpringIn); 78 | var translateYAnimation = new Animation(v => element.TranslationY = v, element.TranslationY, 0, Easing.SpringIn); 79 | var opacityAnimation = new Animation(v => element.Opacity = v, 0, 1, Easing.CubicIn); 80 | 81 | parentAnimation.Add(0, 0.75, translateXAnimation); 82 | parentAnimation.Add(0, 0.75, translateYAnimation); 83 | parentAnimation.Add(0, 1, opacityAnimation); 84 | 85 | parentAnimation.Commit(_associatedObject, "EntranceTransition" + element.Id, 16, Convert.ToUInt32(Duration), null, (v, c) => StopAnimation()); 86 | } 87 | 88 | //bool HasParentEntranceTransition(VisualElement element) 89 | //{ 90 | // VisualElement parent = VisualTreeHelper.GetParent(element); 91 | // var behaviors = parent.Behaviors; 92 | // return behaviors.OfType().FirstOrDefault() != null; 93 | //} 94 | } 95 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/BirdAtlas.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | pdbonly 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /frontend/BirdAtlas/Converters/HabitatTypeToColorConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using BirdAtlas.Models; 4 | using Xamarin.Forms; 5 | 6 | namespace BirdAtlas.Converters 7 | { 8 | public class HabitatTypeToColorConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if(value is HabitatType habitatType) 13 | { 14 | switch(habitatType) 15 | { 16 | case HabitatType.Tundra: 17 | case HabitatType.Grassland: 18 | return (Color)Application.Current.Resources["WarmBlue"]; 19 | case HabitatType.Forest: 20 | case HabitatType.Wetland: 21 | case HabitatType.UrbanSuburban: 22 | return (Color)Application.Current.Resources["LightBlue"]; 23 | case HabitatType.Desert: 24 | case HabitatType.Ocean: 25 | return (Color)Application.Current.Resources["DarkBlue"]; 26 | } 27 | } 28 | 29 | return Color.Default; 30 | } 31 | 32 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Extensions/IEnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace BirdAtlas.Extensions 6 | { 7 | public static class EnumerableExtensions 8 | { 9 | public static IEnumerable Shuffle(this IEnumerable source) 10 | { 11 | return source.Shuffle(new Random()); 12 | } 13 | 14 | public static IEnumerable Shuffle(this IEnumerable source, Random rng) 15 | { 16 | if (source == null) throw new ArgumentNullException("source"); 17 | if (rng == null) throw new ArgumentNullException("rng"); 18 | 19 | return source.ShuffleIterator(rng); 20 | } 21 | 22 | private static IEnumerable ShuffleIterator(this IEnumerable source, Random rng) 23 | { 24 | var buffer = source.ToList(); 25 | for (int i = 0; i < buffer.Count; i++) 26 | { 27 | int j = rng.Next(i, buffer.Count); 28 | yield return buffer[j]; 29 | 30 | buffer[j] = buffer[i]; 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Framework/IDeviceInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BirdAtlas.Framework 4 | { 5 | public interface IDeviceInfo 6 | { 7 | float StatusbarHeight { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Models/Enums.cs: -------------------------------------------------------------------------------- 1 | namespace BirdAtlas.Models 2 | { 3 | public enum PageMode 4 | { 5 | None, 6 | Menu, 7 | Navigate, 8 | Modal 9 | } 10 | 11 | public enum PageAction 12 | { 13 | None, 14 | Settings 15 | } 16 | 17 | public enum HabitatType 18 | { 19 | Forest, 20 | Grassland, 21 | Tundra, 22 | Desert, 23 | Wetland, 24 | Ocean, 25 | UrbanSuburban 26 | } 27 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Models/Habitat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BirdAtlas.Models 4 | { 5 | public class Habitat 6 | { 7 | public string Name { get; set; } 8 | public HabitatType Type { get; set; } 9 | public int Amount { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Models/Nearby.cs: -------------------------------------------------------------------------------- 1 | namespace BirdAtlas.Models 2 | { 3 | public class Nearby 4 | { 5 | public string ImageUrl { get; set; } 6 | public string Name { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Models/Story.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BirdAtlas.Models 4 | { 5 | public class Story 6 | { 7 | public Guid ID { get; set; } 8 | public string ImageUrl { get; set; } 9 | public string Category { get; set; } 10 | public string Title { get; set; } 11 | public bool IsFeatured { get; set; } 12 | public DateTime PublishedOn { get; set; } 13 | public string Author { get; set; } 14 | public string Content { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Services/BirdAtlasMockAPI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using BirdAtlas.Extensions; 6 | using BirdAtlas.Models; 7 | 8 | namespace BirdAtlas.Services 9 | { 10 | public class BirdAtlasMockAPI : IBirdAtlasAPI 11 | { 12 | private List _stories = new List(); 13 | 14 | public BirdAtlasMockAPI() 15 | { 16 | InitStories(); 17 | } 18 | 19 | public Task> GetHabitatsAsync() 20 | { 21 | return null; 22 | } 23 | 24 | public Task> GetNearbiesAsync() 25 | { 26 | return null; 27 | } 28 | 29 | public Task GetStoryAsync(Guid id) 30 | { 31 | return Task.FromResult(_stories.FirstOrDefault(i => i.ID == id)); 32 | } 33 | 34 | public Task> GetStoriesAsync() 35 | { 36 | return Task.FromResult>(_stories); 37 | } 38 | 39 | public Task> GetFeaturedStories(int amount) 40 | { 41 | amount = amount > _stories.Count ? _stories.Count : amount; 42 | return Task.FromResult>(_stories.Shuffle().Take(amount)); 43 | } 44 | 45 | public Task> GetNewestStories(int amount) 46 | { 47 | amount = amount > _stories.Count ? _stories.Count : amount; 48 | return Task.FromResult>(_stories.OrderByDescending(story => story.PublishedOn).Take(amount)); 49 | } 50 | 51 | private void InitStories() 52 | { 53 | //https://stackoverflow.com/questions/41160918/xamarin-forms-image-source-with-ssl 54 | _stories.Add(new Story() { ID = Guid.NewGuid(), IsFeatured = true, PublishedOn = DateTime.Now, Author = "Menno Schilthuizen", Category = "The Wilds", Title = "Why we need to save the scavengers?", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/slider_image/public/slider/arcticternb1_markus_varesvuo-2.jpg" }); 55 | _stories.Add(new Story() { ID = Guid.NewGuid(), IsFeatured = false, PublishedOn = DateTime.Now.AddDays(-1), Author = "Menno Schilthuizen", Category = "Science", Title = "Drunk birds? What is happening...", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/full_620x295/public/news/little_spiderhunter_c_noicherrybeans_shutterstock_smaller_1.jpg" }); 56 | _stories.Add(new Story() { ID = Guid.NewGuid(), IsFeatured = true, PublishedOn = DateTime.Now.AddDays(-2), Author = "Menno Schilthuizen", Category = "The Wilds", Title = "Why we need to save the scavengers?", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/full_620x295/public/news/canada_warbler_c_jayne_gulbrand_smaller.jpg" }); 57 | _stories.Add(new Story() { ID = Guid.NewGuid(), IsFeatured = true, PublishedOn = DateTime.Now.AddDays(-3), Author = "Menno Schilthuizen", Category = "Science", Title = "Drunk birds? What is happening...", ImageUrl = "http://cdn.images.express.co.uk/img/dynamic/13/590x/549233_1.jpg" }); 58 | _stories.Add(new Story() { ID = Guid.NewGuid(), IsFeatured = true, PublishedOn = DateTime.Now.AddDays(-4), Author = "Menno Schilthuizen", Category = "The Wilds", Title = "Why we need to save the scavengers?", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/full_620x295/public/news/rufous_hummingbird_selasphorus_rufus_c_ryan_bushby_1.jpg" }); 59 | _stories.Add(new Story() { ID = Guid.NewGuid(), IsFeatured = false, PublishedOn = DateTime.Now.AddDays(-5), Author = "Menno Schilthuizen", Category = "Science", Title = "Drunk birds? What is happening...", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/third_thumbnail_360x170/public/news/blossomcrown_c_martin_mecnarowski_shutterstock_2.jpg" }); 60 | 61 | foreach (var story in _stories) 62 | story.Content = "A crumbling concrete wall, a ramp and a vast expanse of asphalt on which identical silvery-grey sedans are slowly circling and zigzagging between traffic cones. It does not seem like much but, to urban biologists, the Kadan driving school in the Japanese city of Sendai is hallowed ground. The four of us (the biology students Minoru Chiba and Yawara Takeda, the biologist Iva Njunjić, and I) have been sitting on that crumbling wall for several hours now, hoping to observe what this place is famous for.\r\n\r\nIt was here that, in 1975, the local carrion crows (Corvus corone) discovered how to use cars as nutcrackers. The crows have a predilection for the Japanese walnut (Juglans ailantifolia) that grows abundantly in the city. The pretty nuts (a bit smaller than commercial walnuts"; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /frontend/BirdAtlas/Services/IBirdAtlasAPI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using BirdAtlas.Models; 5 | 6 | namespace BirdAtlas.Services 7 | { 8 | public interface IBirdAtlasAPI 9 | { 10 | Task GetStoryAsync(Guid id); 11 | Task> GetStoriesAsync(); 12 | Task> GetHabitatsAsync(); 13 | Task> GetNearbiesAsync(); 14 | 15 | Task> GetFeaturedStories(int amount); 16 | Task> GetNewestStories(int amount); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /frontend/BirdAtlas/ViewModels/BaseViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using BirdAtlas.Services; 4 | using BirdAtlas.Views; 5 | using Prism.Commands; 6 | using Prism.Mvvm; 7 | using Prism.Navigation; 8 | 9 | namespace BirdAtlas.ViewModels 10 | { 11 | public class BaseViewModel : BindableBase, INavigationAware, IInitializeAsync 12 | { 13 | protected INavigationService NavigationService { get; private set; } 14 | protected IBirdAtlasAPI BirdAtlasAPI { get; private set; } 15 | 16 | private DelegateCommand _navigateBackCommand; 17 | public DelegateCommand NavigateBackCommand => _navigateBackCommand ?? (_navigateBackCommand = new DelegateCommand(async () => await NavigationService.GoBackAsync())); 18 | 19 | private DelegateCommand _settingsCommand; 20 | public DelegateCommand SettingsCommand => _settingsCommand ?? (_settingsCommand = new DelegateCommand(async () => await NavigationService.NavigateAsync("SettingsPage"))); 21 | 22 | public BaseViewModel(IBirdAtlasAPI birdAtlasAPI, INavigationService navigationService) 23 | { 24 | BirdAtlasAPI = birdAtlasAPI; 25 | NavigationService = navigationService; 26 | } 27 | 28 | public void OnNavigatedFrom(INavigationParameters parameters) 29 | { 30 | } 31 | 32 | public virtual void OnNavigatedTo(INavigationParameters parameters) 33 | { 34 | } 35 | 36 | public void OnNavigatingTo(INavigationParameters parameters) 37 | { 38 | } 39 | 40 | public virtual async Task InitializeAsync(INavigationParameters parameters) 41 | { 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/ViewModels/BookmarkViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BirdAtlas.Services; 3 | using Prism.Navigation; 4 | 5 | namespace BirdAtlas.ViewModels 6 | { 7 | public class BookmarkViewModel : BaseViewModel 8 | { 9 | public BookmarkViewModel(IBirdAtlasAPI birdAtlasAPI, INavigationService navigationService) : base(birdAtlasAPI, navigationService) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/ViewModels/DiscoverViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Threading.Tasks; 5 | using BirdAtlas.Models; 6 | using BirdAtlas.Services; 7 | using BirdAtlas.Views; 8 | using Prism.Commands; 9 | using Prism.Navigation; 10 | 11 | namespace BirdAtlas.ViewModels 12 | { 13 | public class DiscoverViewModel : BaseViewModel 14 | { 15 | private ObservableCollection _stories = new ObservableCollection(); 16 | public ObservableCollection Stories 17 | { 18 | get => _stories; 19 | set => SetProperty(ref _stories, value); 20 | } 21 | 22 | private ObservableCollection _habitats = new ObservableCollection(); 23 | public ObservableCollection Habitats 24 | { 25 | get => _habitats; 26 | set => SetProperty(ref _habitats, value); 27 | } 28 | 29 | private ObservableCollection _nearbyBirds = new ObservableCollection(); 30 | public ObservableCollection NearbyBirds 31 | { 32 | get => _nearbyBirds; 33 | set => SetProperty(ref _nearbyBirds, value); 34 | } 35 | 36 | private DelegateCommand _storiesTappedCommand; 37 | public DelegateCommand StoriesTappedCommand => _storiesTappedCommand ?? (_storiesTappedCommand = new DelegateCommand(async () => await NavigationService.NavigateAsync(nameof(StoryOverviewPage)))); 38 | 39 | private DelegateCommand _storyTappedCommand; 40 | public DelegateCommand StoryTappedCommand => _storyTappedCommand ?? (_storyTappedCommand = new DelegateCommand(async story => await NavigationService.NavigateAsync($"{nameof(StoryDetailPage)}?id={story.ID.ToString()}"))); 41 | 42 | public DiscoverViewModel(IBirdAtlasAPI birdAtlasAPI, INavigationService navigationService) : base(birdAtlasAPI, navigationService) 43 | { 44 | Habitats.Add(new Habitat() { Name = "Forests", Type = HabitatType.Forest, Amount = 290 }); 45 | Habitats.Add(new Habitat() { Name = "Tundra", Type = HabitatType.Tundra, Amount = 311 }); 46 | Habitats.Add(new Habitat() { Name = "Deserts", Type = HabitatType.Desert, Amount = 307 }); 47 | 48 | NearbyBirds.Add(new Nearby() { Name = "Eurasian hoopoe", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/third_thumbnail_360x170/public/news/canada_warbler_borb_c_steve_jones.jpg" }); 49 | NearbyBirds.Add(new Nearby() { Name = "Short-eared owl", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/third_thumbnail_360x170/public/news/black-breasted_puffleg_branch_c_murray_cooper_1.jpg" }); 50 | NearbyBirds.Add(new Nearby() { Name = "Raven", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/third_thumbnail_360x170/public/news/marsh_antwren_c_marco_silva.jpg" }); 51 | NearbyBirds.Add(new Nearby() { Name = "Pigeon", ImageUrl = "http://www.birdlife.org/sites/default/files/styles/third_thumbnail_360x170/public/Fujingaho_Magazine/Fujingaho202001/fg2002_jpgjing_sayan_fg2001_taka_01_01.jpg" }); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/ViewModels/SearchViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BirdAtlas.Services; 3 | using Prism.Navigation; 4 | 5 | namespace BirdAtlas.ViewModels 6 | { 7 | public class SearchViewModel : BaseViewModel 8 | { 9 | public SearchViewModel(IBirdAtlasAPI birdAtlasAPI, INavigationService navigationService) : base(birdAtlasAPI, navigationService) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/ViewModels/SettingsViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BirdAtlas.Services; 3 | using Prism.Navigation; 4 | 5 | namespace BirdAtlas.ViewModels 6 | { 7 | public class SettingsViewModel : BaseViewModel 8 | { 9 | public SettingsViewModel(IBirdAtlasAPI birdAtlasAPI, INavigationService navigationService) : base(birdAtlasAPI, navigationService) 10 | { 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /frontend/BirdAtlas/ViewModels/StartViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | using System.Threading.Tasks; 4 | using BirdAtlas.Models; 5 | using BirdAtlas.Services; 6 | using Prism.Navigation; 7 | 8 | namespace BirdAtlas.ViewModels 9 | { 10 | public class StartViewModel : BaseViewModel 11 | { 12 | bool _loaded = false; 13 | 14 | private int _selectedViewModelIndex = 0; 15 | public int SelectedViewModelIndex 16 | { 17 | get => _selectedViewModelIndex; 18 | set => SetProperty(ref _selectedViewModelIndex, value); 19 | } 20 | 21 | public DiscoverViewModel DiscoverViewModel { get; } 22 | public SearchViewModel SearchViewModel { get; } 23 | public BookmarkViewModel BookmarkViewModel { get; } 24 | 25 | public StartViewModel(IBirdAtlasAPI birdAtlasAPI, INavigationService navigationService) : base(birdAtlasAPI, navigationService) 26 | { 27 | DiscoverViewModel = new DiscoverViewModel(BirdAtlasAPI, NavigationService); 28 | SearchViewModel = new SearchViewModel(BirdAtlasAPI, NavigationService); 29 | BookmarkViewModel = new BookmarkViewModel(BirdAtlasAPI, NavigationService); 30 | } 31 | 32 | public async override void OnNavigatedTo(INavigationParameters parameters) 33 | { 34 | if (!_loaded) 35 | { 36 | await Task.WhenAll(new List() 37 | { 38 | { Task.Run(() => GetStoriesAsync()) } 39 | //, { Task.Run(() => BirdAtlasAPI.GetHabitatsAsync()) } 40 | //, { Task.Run(() => BirdAtlasAPI.GetNearbiesAsync()) } 41 | }); 42 | _loaded = true; 43 | } 44 | } 45 | 46 | private async Task GetStoriesAsync() 47 | { 48 | var stories = await BirdAtlasAPI.GetStoriesAsync(); 49 | App.Current.Dispatcher.BeginInvokeOnMainThread(() => DiscoverViewModel.Stories = new ObservableCollection(stories)); 50 | //foreach (var story in stories) 51 | // App.Current.Dispatcher.BeginInvokeOnMainThread(() => DiscoverViewModel.Stories.Add(story)); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/ViewModels/StoryDetailViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BirdAtlas.Models; 3 | using BirdAtlas.Services; 4 | using Prism.Navigation; 5 | 6 | namespace BirdAtlas.ViewModels 7 | { 8 | public class StoryDetailViewModel : BaseViewModel 9 | { 10 | private Story _story; 11 | public Story Story 12 | { 13 | get => _story; 14 | set => SetProperty(ref _story, value); 15 | } 16 | 17 | public StoryDetailViewModel(IBirdAtlasAPI birdAtlasAPI, INavigationService navigationService) : base(birdAtlasAPI, navigationService) 18 | { 19 | } 20 | 21 | public async override void OnNavigatedTo(INavigationParameters parameters) 22 | { 23 | string stringID = parameters["id"] as string; 24 | 25 | if (!string.IsNullOrEmpty(stringID) && Guid.Parse(stringID) is Guid id) 26 | Story = await BirdAtlasAPI.GetStoryAsync(id); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/ViewModels/StoryOverviewViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | using System.Threading.Tasks; 4 | using BirdAtlas.Models; 5 | using BirdAtlas.Services; 6 | using BirdAtlas.Views; 7 | using Prism.Commands; 8 | using Prism.Navigation; 9 | 10 | namespace BirdAtlas.ViewModels 11 | { 12 | public class StoryOverviewViewModel : BaseViewModel 13 | { 14 | private bool _loaded = false; 15 | 16 | private ObservableCollection _featuredStories = new ObservableCollection(); 17 | public ObservableCollection FeaturedStories 18 | { 19 | get => _featuredStories; 20 | set => SetProperty(ref _featuredStories, value); 21 | } 22 | 23 | private ObservableCollection _newStories = new ObservableCollection(); 24 | public ObservableCollection NewStories 25 | { 26 | get => _newStories; 27 | set => SetProperty(ref _newStories, value); 28 | } 29 | 30 | private DelegateCommand _storyItemTappedCommand; 31 | public DelegateCommand StoryItemTappedCommand => _storyItemTappedCommand ?? (_storyItemTappedCommand = new DelegateCommand(async story => await NavigationService.NavigateAsync($"{nameof(StoryDetailPage)}?id={story.ID}"))); 32 | 33 | public StoryOverviewViewModel(IBirdAtlasAPI birdAtlasAPI, INavigationService navigationService) : base(birdAtlasAPI, navigationService) 34 | { 35 | } 36 | 37 | public override async Task InitializeAsync(INavigationParameters parameters) 38 | { 39 | await Task.WhenAll(new List() 40 | { 41 | { Task.Run(() => GetFeaturedStoriesAsync()) } 42 | , { Task.Run(() => GetNewestStoriesAsync()) } 43 | }); 44 | } 45 | 46 | private async Task GetFeaturedStoriesAsync() 47 | { 48 | var featuredStories = await BirdAtlasAPI.GetFeaturedStories(3); 49 | App.Current.Dispatcher.BeginInvokeOnMainThread(() => FeaturedStories = new ObservableCollection(featuredStories)); 50 | //foreach (var story in featuredStories) 51 | // App.Current.Dispatcher.BeginInvokeOnMainThread(() => FeaturedStories.Add(story)); 52 | } 53 | 54 | private async Task GetNewestStoriesAsync() 55 | { 56 | var newStories = await BirdAtlasAPI.GetNewestStories(5); 57 | App.Current.Dispatcher.BeginInvokeOnMainThread(() => NewStories = new ObservableCollection(newStories)); 58 | //foreach (var story in newStories) 59 | // App.Current.Dispatcher.BeginInvokeOnMainThread(() => NewStories.Add(story)); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /frontend/BirdAtlas/Views/BasePage.xaml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |