├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── art ├── apppromo.png ├── platform.png └── web_hi_res_512.png └── src ├── .editorconfig ├── GeoContacts.SharedModels ├── GeoContacts.SharedModels.csproj ├── GraphInfo.cs └── LocationUpdate.cs ├── GeoContacts.iOS.sln ├── GeoContacts.sln ├── GeoContacts ├── GeoContacts.Android │ ├── Assets │ │ └── AboutAssets.txt │ ├── Effects │ │ └── ListViewSelectionOnTopEffect.cs │ ├── GeoContacts.Android.csproj │ ├── MainActivity.cs │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Renderers │ │ └── MarkdownLabelRenderer.cs │ ├── Resources │ │ ├── AboutResources.txt │ │ ├── Resource.designer.cs │ │ ├── color │ │ │ └── icon_tab.xml │ │ ├── drawable-hdpi │ │ │ ├── ic_bitbot.png │ │ │ ├── ic_bitcity.png │ │ │ ├── ic_contacts.png │ │ │ ├── ic_henrybit.png │ │ │ ├── ic_location.png │ │ │ ├── ic_nearby.png │ │ │ ├── ic_settings.png │ │ │ └── icon.png │ │ ├── drawable-mdpi │ │ │ ├── ic_bitbot.png │ │ │ ├── ic_bitcity.png │ │ │ ├── ic_contacts.png │ │ │ ├── ic_henrybit.png │ │ │ ├── ic_location.png │ │ │ ├── ic_nearby.png │ │ │ └── ic_settings.png │ │ ├── drawable-nodpi │ │ │ └── cda_background.jpg │ │ ├── drawable-xhdpi │ │ │ ├── ic_bitbot.png │ │ │ ├── ic_bitcity.png │ │ │ ├── ic_contacts.png │ │ │ ├── ic_henrybit.png │ │ │ ├── ic_location.png │ │ │ ├── ic_nearby.png │ │ │ ├── ic_settings.png │ │ │ └── icon.png │ │ ├── drawable-xxhdpi │ │ │ ├── ic_bitbot.png │ │ │ ├── ic_bitcity.png │ │ │ ├── ic_contacts.png │ │ │ ├── ic_henrybit.png │ │ │ ├── ic_location.png │ │ │ ├── ic_nearby.png │ │ │ ├── ic_settings.png │ │ │ └── icon.png │ │ ├── drawable-xxxhdpi │ │ │ ├── ic_bitbot.png │ │ │ ├── ic_bitcity.png │ │ │ ├── ic_contacts.png │ │ │ ├── ic_henrybit.png │ │ │ ├── ic_location.png │ │ │ ├── ic_nearby.png │ │ │ └── ic_settings.png │ │ ├── drawable │ │ │ ├── background_splash.xml │ │ │ └── icon.png │ │ ├── layout │ │ │ ├── Main.axml │ │ │ ├── Tabbar.axml │ │ │ └── Toolbar.axml │ │ ├── mipmap-hdpi │ │ │ ├── Icon.png │ │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ │ ├── Icon.png │ │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ │ ├── Icon.png │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ │ ├── Icon.png │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── Icon.png │ │ │ └── ic_launcher.png │ │ ├── values-v19 │ │ │ └── styles.xml │ │ ├── values-v21 │ │ │ └── styles.xml │ │ ├── values │ │ │ ├── Strings.xml │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ └── xml │ │ │ └── file_paths.xml │ ├── SplashActivity.cs │ └── mobile-center-post-clone.sh ├── GeoContacts.iOS │ ├── AppDelegate.cs │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-60@2x.png │ │ │ ├── Icon-60@3x.png │ │ │ ├── Icon-76.png │ │ │ ├── Icon-76@2x.png │ │ │ ├── Icon-83.5@2x.png │ │ │ ├── Icon-Notification.png │ │ │ ├── Icon-Notification@2x.png │ │ │ ├── Icon-Notification@3x.png │ │ │ ├── Icon-Small-40.png │ │ │ ├── Icon-Small-40@2x.png │ │ │ ├── Icon-Small-40@3x.png │ │ │ ├── Icon-Small.png │ │ │ ├── Icon-Small@2x.png │ │ │ ├── Icon-Small@3x.png │ │ │ └── iTunesArtwork@2x.png │ ├── Entitlements.plist │ ├── GeoContacts.iOS.csproj │ ├── Info.plist │ ├── Main.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Renderers │ │ ├── MarkdownLabelRenderer.cs │ │ └── TabbedRenderer.cs │ ├── Resources │ │ ├── LaunchScreen.storyboard │ │ ├── cda_background.jpg │ │ ├── ic_bitbot.png │ │ ├── ic_bitbot@2x.png │ │ ├── ic_bitbot@3x.png │ │ ├── ic_bitcity.png │ │ ├── ic_bitcity@2x.png │ │ ├── ic_bitcity@3x.png │ │ ├── ic_contacts.png │ │ ├── ic_contacts@2x.png │ │ ├── ic_contacts@3x.png │ │ ├── ic_contacts_selected.png │ │ ├── ic_contacts_selected@2x.png │ │ ├── ic_contacts_selected@3x.png │ │ ├── ic_henrybit.png │ │ ├── ic_henrybit@2x.png │ │ ├── ic_henrybit@3x.png │ │ ├── ic_location.png │ │ ├── ic_location@2x.png │ │ ├── ic_location@3x.png │ │ ├── ic_nearby.png │ │ ├── ic_nearby@2x.png │ │ ├── ic_nearby@3x.png │ │ ├── ic_nearby_selected.png │ │ ├── ic_nearby_selected@2x.png │ │ ├── ic_nearby_selected@3x.png │ │ ├── ic_settings.png │ │ ├── ic_settings@2x.png │ │ └── ic_settings@3x.png │ └── packages.config └── GeoContacts │ ├── App.xaml │ ├── App.xaml.cs │ ├── Cells │ ├── ContactCell.xaml │ ├── ContactCell.xaml.cs │ ├── ContactsGroupHeader.xaml │ └── ContactsGroupHeader.xaml.cs │ ├── Controls │ └── MarkdownLabel.cs │ ├── Effects │ └── SelectionOnTopEffect.cs │ ├── GeoContacts.csproj │ ├── Helpers │ ├── CommonConstants.cs │ ├── Dialogs.cs │ ├── Settings.cs │ └── TranslationExtension.cs │ ├── Model │ └── Contact.cs │ ├── Resources │ ├── AppResources.Designer.cs │ └── AppResources.resx │ ├── Services │ ├── AuthenticationService.cs │ ├── AzureDataService.cs │ ├── EmotionService.cs │ ├── Geolocation.cs │ ├── IAuthenticationService.cs │ ├── IDataService.cs │ └── MockDataService.cs │ ├── TestPage.xaml │ ├── TestPage.xaml.cs │ ├── View │ ├── AllContactsPage.xaml │ ├── AllContactsPage.xaml.cs │ ├── DetailsPage.xaml │ ├── DetailsPage.xaml.cs │ ├── HomePage.xaml │ ├── HomePage.xaml.cs │ ├── LoginPage.xaml │ ├── LoginPage.xaml.cs │ ├── NearbyPage.xaml │ ├── NearbyPage.xaml.cs │ ├── UpdateLocationPage.xaml │ └── UpdateLocationPage.xaml.cs │ └── ViewModel │ ├── AllContactsViewModel.cs │ ├── DetailsViewModel.cs │ ├── LoginViewModel.cs │ ├── NearbyViewModel.cs │ ├── UpdateLocationViewModel.cs │ └── ViewModelBase.cs ├── GeoContactsFunctions ├── .gitignore ├── GeoContacts.Functions.csproj ├── UpdateGeolocation.cs └── host.json ├── NuGet.Config └── mobile-center-post-clone.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # Benchmark Results 46 | BenchmarkDotNet.Artifacts/ 47 | 48 | # .NET Core 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | **/Properties/launchSettings.json 53 | 54 | *_i.c 55 | *_p.c 56 | *_i.h 57 | *.ilk 58 | *.meta 59 | *.obj 60 | *.pch 61 | *.pdb 62 | *.pgc 63 | *.pgd 64 | *.rsp 65 | *.sbr 66 | *.tlb 67 | *.tli 68 | *.tlh 69 | *.tmp 70 | *.tmp_proj 71 | *.log 72 | *.vspscc 73 | *.vssscc 74 | .builds 75 | *.pidb 76 | *.svclog 77 | *.scc 78 | 79 | # Chutzpah Test files 80 | _Chutzpah* 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opendb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | *.VC.db 91 | *.VC.VC.opendb 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | *.sap 98 | 99 | # TFS 2012 Local Workspace 100 | $tf/ 101 | 102 | # Guidance Automation Toolkit 103 | *.gpState 104 | 105 | # ReSharper is a .NET coding add-in 106 | _ReSharper*/ 107 | *.[Rr]e[Ss]harper 108 | *.DotSettings.user 109 | 110 | # JustCode is a .NET coding add-in 111 | .JustCode 112 | 113 | # TeamCity is a build add-in 114 | _TeamCity* 115 | 116 | # DotCover is a Code Coverage Tool 117 | *.dotCover 118 | 119 | # AxoCover is a Code Coverage Tool 120 | .axoCover/* 121 | !.axoCover/settings.json 122 | 123 | # Visual Studio code coverage results 124 | *.coverage 125 | *.coveragexml 126 | 127 | # NCrunch 128 | _NCrunch_* 129 | .*crunch*.local.xml 130 | nCrunchTemp_* 131 | 132 | # MightyMoose 133 | *.mm.* 134 | AutoTest.Net/ 135 | 136 | # Web workbench (sass) 137 | .sass-cache/ 138 | 139 | # Installshield output folder 140 | [Ee]xpress/ 141 | 142 | # DocProject is a documentation generator add-in 143 | DocProject/buildhelp/ 144 | DocProject/Help/*.HxT 145 | DocProject/Help/*.HxC 146 | DocProject/Help/*.hhc 147 | DocProject/Help/*.hhk 148 | DocProject/Help/*.hhp 149 | DocProject/Help/Html2 150 | DocProject/Help/html 151 | 152 | # Click-Once directory 153 | publish/ 154 | 155 | # Publish Web Output 156 | *.[Pp]ublish.xml 157 | *.azurePubxml 158 | # Note: Comment the next line if you want to checkin your web deploy settings, 159 | # but database connection strings (with potential passwords) will be unencrypted 160 | *.pubxml 161 | *.publishproj 162 | 163 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 164 | # checkin your Azure Web App publish settings, but sensitive information contained 165 | # in these scripts will be unencrypted 166 | PublishScripts/ 167 | 168 | # NuGet Packages 169 | *.nupkg 170 | # The packages folder can be ignored because of Package Restore 171 | **/packages/* 172 | # except build/, which is used as an MSBuild target. 173 | !**/packages/build/ 174 | # Uncomment if necessary however generally it will be regenerated when needed 175 | #!**/packages/repositories.config 176 | # NuGet v3's project.json files produces more ignorable files 177 | *.nuget.props 178 | *.nuget.targets 179 | 180 | # Microsoft Azure Build Output 181 | csx/ 182 | *.build.csdef 183 | 184 | # Microsoft Azure Emulator 185 | ecf/ 186 | rcf/ 187 | 188 | # Windows Store app package directories and files 189 | AppPackages/ 190 | BundleArtifacts/ 191 | Package.StoreAssociation.xml 192 | _pkginfo.txt 193 | *.appx 194 | 195 | # Visual Studio cache files 196 | # files ending in .cache can be ignored 197 | *.[Cc]ache 198 | # but keep track of directories ending in .cache 199 | !*.[Cc]ache/ 200 | 201 | # Others 202 | ClientBin/ 203 | ~$* 204 | *~ 205 | *.dbmdl 206 | *.dbproj.schemaview 207 | *.jfm 208 | *.pfx 209 | *.publishsettings 210 | orleans.codegen.cs 211 | 212 | # Since there are multiple workflows, uncomment next line to ignore bower_components 213 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 214 | #bower_components/ 215 | 216 | # RIA/Silverlight projects 217 | Generated_Code/ 218 | 219 | # Backup & report files from converting an old project file 220 | # to a newer Visual Studio version. Backup files are not needed, 221 | # because we have git ;-) 222 | _UpgradeReport_Files/ 223 | Backup*/ 224 | UpgradeLog*.XML 225 | UpgradeLog*.htm 226 | 227 | # SQL Server files 228 | *.mdf 229 | *.ldf 230 | *.ndf 231 | 232 | # Business Intelligence projects 233 | *.rdl.data 234 | *.bim.layout 235 | *.bim_*.settings 236 | 237 | # Microsoft Fakes 238 | FakesAssemblies/ 239 | 240 | # GhostDoc plugin setting file 241 | *.GhostDoc.xml 242 | 243 | # Node.js Tools for Visual Studio 244 | .ntvs_analysis.dat 245 | node_modules/ 246 | 247 | # Typescript v1 declaration files 248 | typings/ 249 | 250 | # Visual Studio 6 build log 251 | *.plg 252 | 253 | # Visual Studio 6 workspace options file 254 | *.opt 255 | 256 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 257 | *.vbw 258 | 259 | # Visual Studio LightSwitch build output 260 | **/*.HTMLClient/GeneratedArtifacts 261 | **/*.DesktopClient/GeneratedArtifacts 262 | **/*.DesktopClient/ModelManifest.xml 263 | **/*.Server/GeneratedArtifacts 264 | **/*.Server/ModelManifest.xml 265 | _Pvt_Extensions 266 | 267 | # Paket dependency manager 268 | .paket/paket.exe 269 | paket-files/ 270 | 271 | # FAKE - F# Make 272 | .fake/ 273 | 274 | # JetBrains Rider 275 | .idea/ 276 | *.sln.iml 277 | 278 | # CodeRush 279 | .cr/ 280 | 281 | # Python Tools for Visual Studio (PTVS) 282 | __pycache__/ 283 | *.pyc 284 | 285 | # Cake - Uncomment if you are using it 286 | # tools/** 287 | # !tools/packages.config 288 | 289 | # Tabs Studio 290 | *.tss 291 | 292 | # Telerik's JustMock configuration file 293 | *.jmconfig 294 | 295 | # BizTalk build output 296 | *.btp.cs 297 | *.btm.cs 298 | *.odx.cs 299 | *.xsd.cs 300 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 James Montemagno 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # app-geocontacts 2 | 3 | Geo Contacts is a cross-platform mobile contact application sample for iOS and Android built with Xamarin.Forms and leverages several services inside of Azure including Azure AD B2C, Functions, and Cosmos DB. 4 | 5 | See the full session from Build 2018 here: https://channel9.msdn.com/Events/Build/2018/BRK2429?WT.mc_id=appgeocontacts-github-masoucou 6 | 7 | 8 | 9 | 10 | ### Data 11 | Sample data for this application was imported from the [Microsoft Cloud Developer Advocates](https://developer.microsoft.com/advocates/?WT.mc_id=appgeocontacts-github-masoucou) (CDAs). When a CDA logs in (who is part of Azure Active Directory) they are able to update their location anywhere in the world. All users have the ability to skip login and browse our beautiful contact list of CDA and find CDAs that are nearby. 12 | 13 | ## Smarts 14 | Since CDAs travel often to help developers around the world build amazing things we built into the application a way for CDAs to update their current city/state/country and a way for other CDAs to see who is nearby. This leverages built in capabilities of the devices such as geolocation and also leverages advanced geolocation capabilities of CosmosDB for fast queries. 15 | 16 | 17 | ## Services 18 | 19 | ### [Azure Active Directory B2C](https://azure.microsoft.com/services/active-directory-b2c/?WT.mc_id=appgeocontacts-github-masoucou) 20 | Used directly for all authentication in the app. CDAs can log in and we use this authentication with our Azure Function. 21 | 22 | 23 | ### [Cosmos DB](https://azure.microsoft.com/services/cosmos-db/?WT.mc_id=appgeocontacts-github-masoucou) 24 | Our CDAs are located all through the world. We leverage CosmosDB for it's geo-replication to ensure optimal performance in the mobile applications. We also leverage Cosmo sDB advanced queries to get specific data based on the user's geolocation. 25 | 26 | ### [Azure Cognitive Service: Face API](https://azure.microsoft.com/services/cognitive-services/face/?WT.mc_id=appgeocontacts-github-masoucou) 27 | When checking in our CDAs can add their current mood by taking a photo of their face and then the Cognitiver Services API will analyze their emotion and return an emoji to be synced. 28 | 29 | ### [Azure Functions](https://azure.microsoft.com/services/functions/?WT.mc_id=appgeocontacts-github-masoucou) 30 | We use serverless architecture for several features of the application including: 31 | 32 | * Updating geolocation data. The CDA will update their location with an Azure Function that will detect their city/state/country and get an annonymous Latitude and Longitude for that location. This ensure privacy so exact location is not stored. 33 | * This then updates Cosmos DB with their new location. 34 | 35 | ### [Visual Studio App Center](https://appcenter.ms) 36 | Used extensively for Continuous Integration and Deployment, while providing powerful analytics and crash reporting that is imported directly into Application Insights. 37 | 38 | ## Libraries Used 39 | * [Xamarin.Forms](http://xamarin.com/forms) 40 | * [Xamarin.Essentials](https://github.com/xamarin/essentials) 41 | * [Azure Cognitive Service: Face API](https://azure.microsoft.com/services/cognitive-services/face/?WT.mc_id=appgeocontacts-github-masoucou) 42 | * [Media Plugin](http://github.com/jamesmontemagno/mediaplugin) 43 | * [MVVM Helpers](https://github.com/jamesmontemagno/mvvm-helpers) 44 | * [Monkey Cache](https://github.com/jamesmontemagno/monkey-cache) 45 | * [App Center - Build, Distribute, Analytics, Crash](https://appcenter.ms) 46 | * [Multilingual Plugin](https://github.com/CrossGeeks/MultilingualPlugin) 47 | * [Markdig](https://github.com/lunet-io/markdig) 48 | * [Microsoft Identity Client](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet) 49 | * [Azure DocumentDb Core](https://github.com/Azure/azure-documentdb-dotnet) 50 | 51 | ## Art: 52 | * [Bit by Ashley McNamara](https://github.com/ashleymcnamara/Developer-Advocate-Bit) 53 | * [Cloud Neon Sign by Bryan Liston](https://twitter.com/listonb) with permission 54 | 55 | ## License 56 | Under MIT (see license file) 57 | 58 | -------------------------------------------------------------------------------- /art/apppromo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xamarinhq/app-geocontacts/ea1b7f42288ae67ddce9943100241a913bd1ee20/art/apppromo.png -------------------------------------------------------------------------------- /art/platform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xamarinhq/app-geocontacts/ea1b7f42288ae67ddce9943100241a913bd1ee20/art/platform.png -------------------------------------------------------------------------------- /art/web_hi_res_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xamarinhq/app-geocontacts/ea1b7f42288ae67ddce9943100241a913bd1ee20/art/web_hi_res_512.png -------------------------------------------------------------------------------- /src/.editorconfig: -------------------------------------------------------------------------------- 1 | # Suppress: EC112 2 | # top-most EditorConfig file 3 | root = true 4 | 5 | # Don't use tabs for indentation. 6 | [*] 7 | indent_style = space 8 | # (Please don't specify an indent_size here; that has too many unintended consequences.) 9 | 10 | # Code files 11 | [*.{cs,csx,vb,vbx}] 12 | indent_size = 4 13 | 14 | # Code files 15 | [*.sln] 16 | indent_size = 4 17 | 18 | # Xml project files 19 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] 20 | indent_size = 2 21 | 22 | # Xml config files 23 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] 24 | indent_size = 2 25 | 26 | # JSON files 27 | [*.json] 28 | indent_size = 2 29 | 30 | # XML files 31 | [*.xml] 32 | indent_size = 2 33 | 34 | # Dotnet code style settings: 35 | [*.{cs,vb}] 36 | # Sort using and Import directives with System.* appearing first 37 | dotnet_sort_system_directives_first = true 38 | # Avoid "this." and "Me." if not necessary 39 | dotnet_style_qualification_for_field = false:suggestion 40 | dotnet_style_qualification_for_property = false:suggestion 41 | dotnet_style_qualification_for_method = false:suggestion 42 | dotnet_style_qualification_for_event = false:suggestion 43 | 44 | # Use language keywords instead of framework type names for type references 45 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 46 | dotnet_style_predefined_type_for_member_access = true:suggestion 47 | dotnet_style_require_accessibility_modifiers = omit_if_default:warning 48 | 49 | # Suggest more modern language features when available 50 | dotnet_style_object_initializer = true:suggestion 51 | dotnet_style_collection_initializer = true:suggestion 52 | dotnet_style_coalesce_expression = true:suggestion 53 | dotnet_style_null_propagation = true:suggestion 54 | dotnet_style_explicit_tuple_names = true:suggestion 55 | 56 | # Naming Conventions: 57 | # Pascal Casing 58 | dotnet_naming_symbols.method_and_property_symbols.applicable_kinds= method,property,enum 59 | dotnet_naming_symbols.method_and_property_symbols.applicable_accessibilities = * 60 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case 61 | 62 | dotnet_naming_rule.methods_and_properties_must_be_pascal_case.severity = warning 63 | dotnet_naming_rule.methods_and_properties_must_be_pascal_case.symbols = method_and_property_symbols 64 | dotnet_naming_rule.methods_and_properties_must_be_pascal_case.style = pascal_case_style 65 | 66 | # Non-public members must be lower-case 67 | dotnet_naming_symbols.non_public_symbols.applicable_kinds = field 68 | dotnet_naming_symbols.non_public_symbols.applicable_accessibilities = private 69 | dotnet_naming_style.all_lower_case_style.capitalization = camel_case 70 | 71 | dotnet_naming_rule.non_public_members_must_be_lower_case.severity = warning 72 | dotnet_naming_rule.non_public_members_must_be_lower_case.symbols = non_public_symbols 73 | dotnet_naming_rule.non_public_members_must_be_lower_case.style = all_lower_case_style 74 | 75 | # CSharp code style settings: 76 | [*.cs] 77 | # Do not prefer "var" everywhere 78 | csharp_style_var_for_built_in_types = true:error 79 | csharp_style_var_when_type_is_apparent = true:error 80 | csharp_style_var_elsewhere = true:error 81 | 82 | # Prefer method-like constructs to have a block body 83 | csharp_style_expression_bodied_methods = true:suggestion 84 | csharp_style_expression_bodied_constructors = true:suggestion 85 | csharp_style_expression_bodied_operators = true:suggestion 86 | 87 | # Prefer property-like constructs to have an expression-body 88 | csharp_style_expression_bodied_properties = true:suggestion 89 | csharp_style_expression_bodied_indexers = true:suggestion 90 | csharp_style_expression_bodied_accessors = true:suggestion 91 | 92 | # Suggest more modern language features when available 93 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 94 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 95 | csharp_style_inlined_variable_declaration = true:suggestion 96 | csharp_style_throw_expression = true:suggestion 97 | csharp_style_conditional_delegate_call = true:suggestion 98 | 99 | # Newline settings 100 | csharp_new_line_before_open_brace = all 101 | csharp_new_line_before_else = true 102 | csharp_new_line_before_catch = true 103 | csharp_new_line_before_finally = true 104 | csharp_new_line_before_members_in_object_initializers = true 105 | csharp_new_line_before_members_in_anonymous_types = true 106 | 107 | -------------------------------------------------------------------------------- /src/GeoContacts.SharedModels/GeoContacts.SharedModels.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/GeoContacts.SharedModels/GraphInfo.cs: -------------------------------------------------------------------------------- 1 | // To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: 2 | // 3 | // using GeoContacts.SharedModels; 4 | // 5 | // var data = GraphInfo.FromJson(jsonString); 6 | 7 | namespace GeoContacts.SharedModels 8 | { 9 | using System; 10 | using System.Net; 11 | using System.Collections.Generic; 12 | 13 | using Newtonsoft.Json; 14 | 15 | public partial class GraphInfo 16 | { 17 | [JsonProperty("@odata.context")] 18 | public string OdataContext { get; set; } 19 | 20 | [JsonProperty("id")] 21 | public string Id { get; set; } 22 | 23 | [JsonProperty("businessPhones")] 24 | public List BusinessPhones { get; set; } 25 | 26 | [JsonProperty("displayName")] 27 | public string DisplayName { get; set; } 28 | 29 | [JsonProperty("givenName")] 30 | public string GivenName { get; set; } 31 | 32 | [JsonProperty("jobTitle")] 33 | public string JobTitle { get; set; } 34 | 35 | [JsonProperty("mail")] 36 | public string Mail { get; set; } 37 | 38 | [JsonProperty("mobilePhone")] 39 | public object MobilePhone { get; set; } 40 | 41 | [JsonProperty("officeLocation")] 42 | public string OfficeLocation { get; set; } 43 | 44 | [JsonProperty("preferredLanguage")] 45 | public object PreferredLanguage { get; set; } 46 | 47 | [JsonProperty("surname")] 48 | public string Surname { get; set; } 49 | 50 | [JsonProperty("userPrincipalName")] 51 | public string UserPrincipalName { get; set; } 52 | } 53 | 54 | public partial class GraphInfo 55 | { 56 | public static GraphInfo FromJson(string json) => JsonConvert.DeserializeObject(json, GeoContacts.SharedModels.Converter.Settings); 57 | } 58 | 59 | public static class Serialize 60 | { 61 | public static string ToJson(this GraphInfo self) => JsonConvert.SerializeObject(self, GeoContacts.SharedModels.Converter.Settings); 62 | } 63 | 64 | public class Converter 65 | { 66 | public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings 67 | { 68 | MetadataPropertyHandling = MetadataPropertyHandling.Ignore, 69 | DateParseHandling = DateParseHandling.None, 70 | }; 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/GeoContacts.SharedModels/LocationUpdate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Azure.Documents.Spatial; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | namespace GeoContacts.SharedModels 8 | { 9 | public class LocationUpdate 10 | { 11 | [JsonProperty("position")] 12 | public Point Position { get; set; } 13 | 14 | [JsonProperty("id")] 15 | public string Id { get; set; } 16 | public string Country { get; set; } 17 | public string Town { get; set; } 18 | public string State { get; set; } 19 | [JsonProperty("userPrincipalName")] 20 | public string UserPrincipalName { get; set; } 21 | public DateTimeOffset InsertTime { get; set; } 22 | public string Mood { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/GeoContacts/GeoContacts.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 | -------------------------------------------------------------------------------- /src/GeoContacts/GeoContacts.Android/Effects/ListViewSelectionOnTopEffect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Platform.Android; 4 | using Android.Widget; 5 | using GeoContacts.Droid.Effects; 6 | 7 | [assembly: ResolutionGroupName("Microsoft")] 8 | [assembly: ExportEffect(typeof(ListViewSelectionOnTopEffect), "ListViewSelectionOnTopEffect")] 9 | namespace GeoContacts.Droid.Effects 10 | { 11 | public class ListViewSelectionOnTopEffect : PlatformEffect 12 | { 13 | protected override void OnAttached() 14 | { 15 | try 16 | { 17 | var listView = Control as AbsListView; 18 | 19 | if (listView == null) 20 | return; 21 | 22 | listView.SetDrawSelectorOnTop(true); 23 | } 24 | catch (Exception ex) 25 | { 26 | 27 | } 28 | } 29 | 30 | protected override void OnDetached() 31 | { 32 | 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/GeoContacts/GeoContacts.Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 |  2 | using Android.App; 3 | using Android.Content.PM; 4 | using Android.Runtime; 5 | using Android.OS; 6 | using ImageCircle.Forms.Plugin.Droid; 7 | using Android.Content; 8 | using Microsoft.Identity.Client; 9 | 10 | namespace GeoContacts.Droid 11 | { 12 | [Activity(Label = "CDA Contacts", Icon = "@mipmap/ic_launcher", 13 | Theme = "@style/MainTheme", 14 | MainLauncher = false, 15 | 16 | LaunchMode = LaunchMode.SingleTask, 17 | ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, ScreenOrientation = ScreenOrientation.Portrait)] 18 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 19 | { 20 | protected override void OnCreate(Bundle bundle) 21 | { 22 | TabLayoutResource = Resource.Layout.Tabbar; 23 | ToolbarResource = Resource.Layout.Toolbar; 24 | 25 | base.OnCreate(bundle); 26 | 27 | global::Xamarin.Forms.Forms.Init(this, bundle); 28 | ImageCircleRenderer.Init(); 29 | Android.Glide.Forms.Init(); 30 | FormsToolkit.Droid.Toolkit.Init(); 31 | 32 | Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity = this; 33 | 34 | Xamarin.Essentials.Platform.Init(this, bundle); 35 | 36 | LoadApplication(new App()); 37 | 38 | AuthenticationService.UIParent = new UIParent(this); 39 | } 40 | 41 | protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) 42 | { 43 | base.OnActivityResult(requestCode, resultCode, data); 44 | 45 | AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data); 46 | } 47 | 48 | public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults) 49 | { 50 | Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); 51 | Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults); 52 | base.OnRequestPermissionsResult(requestCode, permissions, grantResults); 53 | 54 | } 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/GeoContacts/GeoContacts.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/GeoContacts/GeoContacts.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("GeoContacts.Android")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("GeoContacts.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 | [assembly: UsesPermission(Android.Manifest.Permission.Camera)] 36 | 37 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)] 38 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)] 39 | [assembly: UsesFeature("android.hardware.location", Required = false)] 40 | [assembly: UsesFeature("android.hardware.location.gps", Required = false)] 41 | [assembly: UsesFeature("android.hardware.location.network", Required = false)] 42 | -------------------------------------------------------------------------------- /src/GeoContacts/GeoContacts.Android/Renderers/MarkdownLabelRenderer.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Android.Text; 3 | using GeoContacts.Controls; 4 | using GeoContacts.Droid.Renderers; 5 | using Markdig; 6 | using Xamarin.Forms; 7 | using Xamarin.Forms.Platform.Android; 8 | 9 | [assembly: ExportRenderer(typeof(MarkdownLabel), typeof(MarkdownLabelRenderer))] 10 | namespace GeoContacts.Droid.Renderers 11 | { 12 | public class MarkdownLabelRenderer : LabelRenderer 13 | { 14 | public MarkdownLabelRenderer() 15 | : base () 16 | { 17 | 18 | } 19 | 20 | protected override void OnElementChanged(ElementChangedEventArgs