diff --git a/README.md b/README.md
index 69076284b..0a950b657 100644
--- a/README.md
+++ b/README.md
@@ -20,15 +20,15 @@ JHipster provides a blueprints system that allows to override the default behavi
JHipster.NET is a blueprint that overrides the back-end part, originally generated in spring boot, by back-end in asp.net core. For the front-end all the common language can be used (angular, react).
-In alpha version we have also the possibility to choose Blazor for the front. [Blazor as front issue](https://github.com/jhipster/jhipster-dotnetcore/issues/165)
+In alpha version we also have the possibility to choose either [Blazor](https://github.com/jhipster/jhipster-dotnetcore/issues/165) or [Xamarin](https://github.com/jhipster/jhipster-dotnetcore/issues/488) for the front.
-This blueprint it's an official blueprint of jhipster [official-blueprints](https://www.jhipster.tech/modules/official-blueprints/)
+This blueprint is an official blueprint of JHipster [official-blueprints](https://www.jhipster.tech/modules/official-blueprints/)
# Docs
-Documentation and information about `JHipster.NET ` is available [here](https://jhipsternet.readthedocs.io/en/latest/)
+Documentation and information about `JHipster.NET` are available [here](https://jhipsternet.readthedocs.io/en/latest/)
-Full documentation and information about JHipster is available [here](https://www.jhipster.tech/)
+Full documentation and information about JHipster are available [here](https://www.jhipster.tech/)
# Analysis of the sample project
https://github.com/jhipster/jhipster-sample-app-dotnetcore
diff --git a/docs/Features/fronts.md b/docs/Features/fronts.md
index 0e88e08e6..7103fd824 100644
--- a/docs/Features/fronts.md
+++ b/docs/Features/fronts.md
@@ -1,3 +1,70 @@
+# Fronts
+
+When generating an application, you are able to choose between multiple fronts.
+![front-choice](../assets/Front-choice.png)
+
+## Angular
+
+Angular (commonly referred to as "Angular 2+" or "Angular v2 and above") is a TypeScript-based open-source web application framework.
+
+## React
+
+React (also known as React.js or ReactJS) is an open-source, front end, JavaScript library for building user interfaces or UI components.
+
+## Alpha - Blazor
+
+Blazor is a free and open-source web framework that enables developers to create web apps using C# and HTML.
+
+## Alpha - Xamarin
+
+With a C#-shared codebase, developers can use Xamarin tools to write native Android, iOS, and Windows apps with native user interfaces and share code across multiple platforms, including Windows, macOS, and Linux.
+
+### Available features
+
+- Handle registration and connection.
+- Sidebar menu to navigate through pages.
+- Entities and users management.
+- Auto-generated entity models, services, views and viewmodels.
+
+### NuGet requirements
+
+- [akavache](https://www.nuget.org/packages/akavache/) >= 7.1.1
+- [MvvmCross.Forms](https://www.nuget.org/packages/MvvmCross.Forms/) >= 7.1.1
+- [System.ComponentModel.Annotations](https://www.nuget.org/packages/System.ComponentModel.Annotations/) >= 5.0.0
+- [System.Net.Http.Json](https://www.nuget.org/packages/System.Net.Http.Json/) >= 3.2.1
+- [Xamarin.Forms](https://www.nuget.org/packages/Xamarin.Forms) >= 4.6.0
+- [Xamarin.Essential](https://www.nuget.org/packages/Xamarin.Essentials/) >=1.5.3
+
+### Why Xamarin
+
+Xamarin allows to take advantage of this blueprint. Indeed, it enables to generate a modern cross platform application with both front-end and back-end in C#.
+
+### Structure
+
+Any generated Xamarin application is structured as follows
+```
+client
+├── Namespace.Client.Xamarin.Core - Your core application
+│ ├── Models
+│ │ ├── Entities - Generated models
+│ ├── Services
+│ │ ├── Entities - Generated services
+│ ├── ViewModels
+│ │ ├── Entities - Generated viewmodels
+│ ├── Views
+│ │ ├── Entities - Generated views
+├── Namespace.Client.Xamarin.Android - Your Android application
+│ ├── Resources
+│ │ ├── drawable - Contains your images
+│ │ ├── Layout - Contains your layouts
+│ ├── Properties
+├── Namespace.Client.Xamarin.iOS - Your iOS application
+│ ├── Resources - Contains your images
+│ ├── Properties
+├── Namespace.Client.Xamarin.Shared - Shared code
+│ ├── Constants - Contains shared constants
+```
+
# Fronts
## Using Blazor
diff --git a/docs/Introduction/big-picture.md b/docs/Introduction/big-picture.md
index 9529fe702..c56d174e4 100644
--- a/docs/Introduction/big-picture.md
+++ b/docs/Introduction/big-picture.md
@@ -5,6 +5,6 @@ JHipster provides a blueprints system that allows to override the default behavi
JHipster.NET is a blueprint that overrides the back-end part, originally generated in spring boot, by back-end in asp.net core. For the front-end all the common language can be used (angular, react).
-In alpha version we have also the possibility to choose Blazor for the front. [Blazor as front issue](https://github.com/jhipster/jhipster-dotnetcore/issues/165)
+In alpha version we also have the possibility to choose either [Blazor](https://github.com/jhipster/jhipster-dotnetcore/issues/165) or [Xamarin](https://github.com/jhipster/jhipster-dotnetcore/issues/488) for the front.
-This blueprint it's an official blueprint of jhipster [official-blueprints](https://www.jhipster.tech/modules/official-blueprints/)
\ No newline at end of file
+This blueprint is an official blueprint of JHipster [official-blueprints](https://www.jhipster.tech/modules/official-blueprints/)
\ No newline at end of file
diff --git a/docs/assets/Front-choice.png b/docs/assets/Front-choice.png
new file mode 100644
index 000000000..d0f9f4031
Binary files /dev/null and b/docs/assets/Front-choice.png differ
diff --git a/generators/client/files-xamarin.js b/generators/client/files-xamarin.js
new file mode 100644
index 000000000..40b0e3dcf
--- /dev/null
+++ b/generators/client/files-xamarin.js
@@ -0,0 +1,792 @@
+/**
+ * Copyright 2013-2020 the original author or authors from the JHipster project.
+ *
+ * This file is part of the JHipster project, see https://www.jhipster.tech/
+ * for more information.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const constants = require('../generator-dotnetcore-constants');
+
+/* Constants use throughout */
+const CLIENT_SRC_DIR = constants.CLIENT_SRC_DIR;
+const CLIENT_TEST_DIR = constants.CLIENT_TEST_DIR;
+
+/**
+ * The default is to use a file path string. It implies use of the template method.
+ * For any other config an object { file:.., method:.., template:.. } can be used
+ */
+const files = {
+ xamarinAppModels: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Models/RegisterResultRequest.cs',
+ renameTo: generator => `${generator.mainClientDir}/Models/RegisterResultRequest.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Models/UserSaveModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/Models/UserSaveModel.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Models/JwtToken.cs',
+ renameTo: generator => `${generator.mainClientDir}/Models/JwtToken.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Models/LoginModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/Models/LoginModel.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Models/UserModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/Models/UserModel.cs`,
+ },
+ ],
+ },
+ ],
+ xamarinAppViews: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/HomeView.xaml.cs',
+ renameTo: generator => `${generator.mainClientDir}/Views/HomeView.xaml.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/HomeView.xaml',
+ renameTo: generator => `${generator.mainClientDir}/Views/HomeView.xaml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/LoginView.xaml.cs',
+ renameTo: generator => `${generator.mainClientDir}/Views/LoginView.xaml.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/LoginView.xaml',
+ renameTo: generator => `${generator.mainClientDir}/Views/LoginView.xaml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/MenuPage.xaml.cs',
+ renameTo: generator => `${generator.mainClientDir}/Views/MenuPage.xaml.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/MenuPage.xaml',
+ renameTo: generator => `${generator.mainClientDir}/Views/MenuPage.xaml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/RegisterView.xaml.cs',
+ renameTo: generator => `${generator.mainClientDir}/Views/RegisterView.xaml.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/RegisterView.xaml',
+ renameTo: generator => `${generator.mainClientDir}/Views/RegisterView.xaml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/WelcomeView.xaml.cs',
+ renameTo: generator => `${generator.mainClientDir}/Views/WelcomeView.xaml.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Views/WelcomeView.xaml',
+ renameTo: generator => `${generator.mainClientDir}/Views/WelcomeView.xaml`,
+ },
+ ],
+ }
+ ],
+ xamarinAppViewModels: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/ViewModels/BaseViewModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/ViewModels/BaseViewModel.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/ViewModels/HomeViewModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/ViewModels/HomeViewModel.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/ViewModels/LoginViewModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/ViewModels/LoginViewModel.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/ViewModels/MenuViewModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/ViewModels/MenuViewModel.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/ViewModels/RegisterViewModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/ViewModels/RegisterViewModel.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/ViewModels/WelcomeViewModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/ViewModels/WelcomeViewModel.cs`,
+ },
+ ],
+ }
+ ],
+ xamarinAppServices: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Services/Configuration.cs',
+ renameTo: generator => `${generator.mainClientDir}/Services/Configuration.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Services/IAuthenticationService.cs',
+ renameTo: generator => `${generator.mainClientDir}/Services/IAuthenticationService.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Services/AuthenticationService.cs',
+ renameTo: generator => `${generator.mainClientDir}/Services/AuthenticationService.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Services/IAbstractEntityService.cs',
+ renameTo: generator => `${generator.mainClientDir}/Services/IAbstractEntityService.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Services/AbstractEntityService.cs',
+ renameTo: generator => `${generator.mainClientDir}/Services/AbstractEntityService.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Services/IRegisterService.cs',
+ renameTo: generator => `${generator.mainClientDir}/Services/IRegisterService.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Services/RegisterService.cs',
+ renameTo: generator => `${generator.mainClientDir}/Services/RegisterService.cs`,
+ },
+ ],
+ }
+ ],
+ xamarinAppResources: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Resources/Strings.Designer.cs',
+ renameTo: generator => `${generator.mainClientDir}/Resources/Strings.Designer.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Resources/Strings.resx',
+ renameTo: generator => `${generator.mainClientDir}/Resources/Strings.resx`,
+ },
+ ],
+ }
+ ],
+ xamarinAppBase: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/App.cs',
+ renameTo: generator => `${generator.mainClientDir}/App.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/AssemblyInfo.cs',
+ renameTo: generator => `${generator.mainClientDir}/AssemblyInfo.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/FormsApp.xaml.cs',
+ renameTo: generator => `${generator.mainClientDir}/FormsApp.xaml.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/FormsApp.xaml',
+ renameTo: generator => `${generator.mainClientDir}/FormsApp.xaml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/LinkerPreserve.cs',
+ renameTo: generator => `${generator.mainClientDir}/LinkerPreserve.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Core/Project.Client.Xamarin.Core.csproj',
+ renameTo: generator => `${generator.mainClientDir}/${generator.pascalizedBaseName}.Client.Xamarin.Core.csproj`,
+ },
+ ],
+ }
+ ],
+ xamarinAppShared: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Shared/Constants/ErrorConst.cs',
+ renameTo: generator => `${generator.sharedClientDir}/Constants/ErrorConst.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Shared/Project.Client.Xamarin.Shared.csproj',
+ renameTo: generator => `${generator.sharedClientDir}/${generator.pascalizedBaseName}.Client.Xamarin.Shared.csproj`,
+ },
+ ],
+ }
+ ],
+ xamarinAppAndroid: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Project.Client.Xamarin.Android.csproj',
+ renameTo: generator => `${generator.androidClientDir}/${generator.pascalizedBaseName}.Client.Xamarin.Android.csproj`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/MainActivity.cs',
+ renameTo: generator => `${generator.androidClientDir}/MainActivity.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/SplashScreenActivity.cs',
+ renameTo: generator => `${generator.androidClientDir}/SplashScreenActivity.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Project.Client.Xamarin.Android.csproj.user',
+ renameTo: generator => `${generator.androidClientDir}/${generator.pascalizedBaseName}.Client.Xamarin.Android.csproj.user`,
+ },
+ ],
+ }
+ ],
+ xamarinAppAndroidResourcesValues: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/values/colors.xml',
+ renameTo: generator => `${generator.androidClientDir}/Resources/values/colors.xml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/values/styles.xml',
+ renameTo: generator => `${generator.androidClientDir}/Resources/values/styles.xml`,
+ },
+ ],
+ }
+ ],
+ xamarinAppAndroidResourcesLayout: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/Layout/Tabbar.xml',
+ renameTo: generator => `${generator.androidClientDir}/Resources/Layout/Tabbar.xml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/Layout/Toolbar.xml',
+ renameTo: generator => `${generator.androidClientDir}/Resources/Layout/Toolbar.xml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/Layout/SplashScreen.xml',
+ renameTo: generator => `${generator.androidClientDir}/Resources/Layout/SplashScreen.xml`,
+ },
+ ],
+ },
+ ],
+ xamarinAppAndroidResourcesImage: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/drawable/splashscreen.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/drawable/splashscreen.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/drawable/menu.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/drawable/menu.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-anydpi-v26/icon.xml',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-anydpi-v26/icon.xml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-anydpi-v26/icon_round.xml',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-anydpi-v26/icon_round.xml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-hdpi/icon.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-hdpi/icon.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-hdpi/launcher_foreground.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-hdpi/launcher_foreground.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-mdpi/icon.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-mdpi/icon.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-mdpi/launcher_foreground.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-mdpi/launcher_foreground.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-xhdpi/icon.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-xhdpi/icon.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-xhdpi/launcher_foreground.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-xhdpi/launcher_foreground.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-xxhdpi/icon.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-xxhdpi/icon.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-xxhdpi/launcher_foreground.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-xxhdpi/launcher_foreground.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-xxxhdpi/icon.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-xxxhdpi/icon.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png',
+ method: 'copy',
+ renameTo: generator => `${generator.androidClientDir}/Resources/mipmap-xxxhdpi/launcher_foreground.png`,
+ },
+ ],
+ },
+ ],
+ xamarinAppAndroidProperties: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Properties/AndroidManifest.xml',
+ renameTo: generator => `${generator.androidClientDir}/Properties/AndroidManifest.xml`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.Android/Properties/AssemblyInfo.cs',
+ renameTo: generator => `${generator.androidClientDir}/Properties/AssemblyInfo.cs`,
+ },
+ ],
+ }
+ ],
+ xamarinAppiOS: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Project.Client.Xamarin.iOS.csproj',
+ renameTo: generator => `${generator.iOSClientDir}/${generator.pascalizedBaseName}.Client.Xamarin.iOS.csproj`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Project.Client.Xamarin.iOS.csproj.user',
+ renameTo: generator => `${generator.iOSClientDir}/${generator.pascalizedBaseName}.Client.Xamarin.iOS.csproj.user`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Main.cs',
+ renameTo: generator => `${generator.iOSClientDir}/Main.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Info.plist',
+ renameTo: generator => `${generator.iOSClientDir}/Info.plist`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Entitlements.plist',
+ method: 'copy',
+ renameTo: generator => `${generator.iOSClientDir}/Entitlements.plist`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/AppDelegate.cs',
+ renameTo: generator => `${generator.iOSClientDir}/AppDelegate.cs`,
+ },
+ ],
+ }
+ ],
+ xamarinAppiOSProperties: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Properties/AssemblyInfo.cs',
+ renameTo: generator => `${generator.iOSClientDir}/Properties/AssemblyInfo.cs`,
+ },
+ ],
+ }
+ ],
+ xamarinAppiOSResources: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Resources/LaunchScreen.storyboard',
+ renameTo: generator => `${generator.iOSClientDir}/Resources/LaunchScreen.storyboard`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Resources/Default.png',
+ method: 'copy',
+ renameTo: generator => `${generator.iOSClientDir}/Resources/Default.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Resources/Default@2x.png',
+ method: 'copy',
+ renameTo: generator => `${generator.iOSClientDir}/Resources/Default@2x.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Resources/Default-568h@2x.png',
+ method: 'copy',
+ renameTo: generator => `${generator.iOSClientDir}/Resources/Default.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Resources/Default-Portrait@2x.png',
+ method: 'copy',
+ renameTo: generator => `${generator.iOSClientDir}/Resources/Default-Portrait@2x.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Resources/Default-Portrait.png',
+ method: 'copy',
+ renameTo: generator => `${generator.iOSClientDir}/Resources/Default-Portrait.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Resources/menu.png',
+ method: 'copy',
+ renameTo: generator => `${generator.iOSClientDir}/Resources/menu.png`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client.Xamarin.iOS/Resources/splashscreen.png',
+ method: 'copy',
+ renameTo: generator => `${generator.iOSClientDir}/Resources/splashscreen.png`,
+ },
+ ],
+ },
+ ],
+};
+
+module.exports = {
+ writeFiles,
+ files,
+};
+
+function writeFiles() {
+ this.writeFilesToDisk(files, this, false, 'xamarin');
+}
+
diff --git a/generators/client/index.js b/generators/client/index.js
index f2c6e33ec..481769fa5 100644
--- a/generators/client/index.js
+++ b/generators/client/index.js
@@ -32,10 +32,12 @@ const dotnet = require('../dotnet');
const writeAngularFiles = require('./files-angular').writeFiles;
const writeReactFiles = require('./files-react').writeFiles;
const writeBlazorFiles = require('./files-blazor').writeFiles;
+const writeXamarinFiles = require('./files-xamarin').writeFiles;
const writeCommonFiles = require('./files-common').writeFiles;
const REACT = baseConstants.SUPPORTED_CLIENT_FRAMEWORKS.REACT;
const BLAZOR = constants.BLAZOR;
+const XAMARIN = constants.XAMARIN;
module.exports = class extends ClientGenerator {
constructor(args, opts) {
@@ -106,6 +108,8 @@ module.exports = class extends ClientGenerator {
switch (this.clientFramework) {
case BLAZOR:
return writeBlazorFiles.call(this);
+ case XAMARIN:
+ return writeXamarinFiles.call(this);
case REACT:
baseWriteReactFiles.call(this);
writeCommonFiles.call(this);
@@ -160,6 +164,29 @@ module.exports = class extends ClientGenerator {
)
);
dotnet.installBlazorDependencies();
+ } else if (this.clientFramework === XAMARIN) {
+ this.log(chalk.green.bold(`\nCreating ${this.solutionName} .Net Core solution if it does not already exist.\n`));
+ try {
+ await dotnet.newSln(this.solutionName);
+ } catch (err) {
+ this.warning(`Failed to create ${this.solutionName} .Net Core solution: ${err}`);
+ }
+ await dotnet.slnAdd(`${this.solutionName}.sln`, [
+ `${constants.CLIENT_SRC_DIR}${this.mainClientDir}/${this.pascalizedBaseName}.Client.Xamarin.Core.csproj`,
+ `${constants.CLIENT_SRC_DIR}${this.sharedClientDir}/${this.pascalizedBaseName}.Client.Xamarin.Shared.csproj`,
+ ]);
+ await dotnet.newSlnAddProj(this.solutionName, [
+ {
+ 'path': `${constants.CLIENT_SRC_DIR}${this.androidClientDir}/${this.pascalizedBaseName}.Client.Xamarin.Android.csproj`,
+ 'name' : `${this.pascalizedBaseName}.Client.Xamarin.Android`
+ },
+ {
+ 'path': `${constants.CLIENT_SRC_DIR}${this.iOSClientDir}/${this.pascalizedBaseName}.Client.Xamarin.iOS.csproj`,
+ 'name' : `${this.pascalizedBaseName}.Client.Xamarin.iOS`
+ }
+ ]);
+ this.log(chalk.green.bold('\Client application generated successfully.\n'));
+
} else {
if (this.skipClient) return;
this.log(chalk.green.bold('\nClient application generated successfully.\n'));
diff --git a/generators/client/needle-api/needle-client-xamarin.js b/generators/client/needle-api/needle-client-xamarin.js
new file mode 100644
index 000000000..ee3734b1a
--- /dev/null
+++ b/generators/client/needle-api/needle-client-xamarin.js
@@ -0,0 +1,97 @@
+/**
+ * Copyright 2013-2020 the original author or authors from the JHipster project.
+ *
+ * This file is part of the JHipster project, see https://www.jhipster.tech/
+ * for more information.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const needleBase = require('generator-jhipster/generators/needle-base');
+const chalk = require('chalk');
+const _ = require('lodash');
+
+module.exports = class extends needleBase {
+ constructor(generator) {
+ super(generator);
+
+ this.mainClientDir = generator.mainClientDir;
+
+ if (!this.mainClientDir) {
+ generator.error('Client destination folder is missing');
+ }
+ }
+
+ addEntityToMenu(entityName) {
+ const errorMessage = `${chalk.yellow('Reference to ') + entityName} ${chalk.yellow('not added to menu.\n')}`;
+ const entityMenuPath = `src/${this.mainClientDir}/Views/MenuPage.xaml`;
+ const entityEntry =
+ // prettier-ignore
+ this.generator.stripMargin(
+ `|
+ |
+ |
+ |
+ |
+ |
+ |`);
+
+ const rewriteFileModel = this.generateFileModel(entityMenuPath, 'jhipster-needle-add-entity-to-menu', entityEntry);
+
+ this.addBlockContentToFile(rewriteFileModel, errorMessage);
+ }
+
+ declareCommandToMenu(entityName) {
+ const errorMessage = `${chalk.yellow('Reference to ') + entityName} ${chalk.yellow('not added to menu.\n')}`;
+ const entityMenuPath = `src/${this.mainClientDir}/ViewModels/MenuViewModel.cs`;
+ const entityEntry =
+ // prettier-ignore
+ this.generator.stripMargin(
+ `|public IMvxCommand Show${entityName}Command => new MvxAsyncCommand(${entityName}CommandClicked);`);
+
+ const rewriteFileModel = this.generateFileModel(entityMenuPath, 'jhipster-needle-declare-entity-command', entityEntry);
+
+ this.addBlockContentToFile(rewriteFileModel, errorMessage);
+ }
+
+ addCommandToMenu(entityName) {
+ const errorMessage = `${chalk.yellow('Reference to ') + entityName} ${chalk.yellow('not added to menu.\n')}`;
+ const entityMenuPath = `src/${this.mainClientDir}/ViewModels/MenuViewModel.cs`;
+ const entityEntry =
+ // prettier-ignore
+ this.generator.stripMargin(
+ `|private async Task ${entityName}CommandClicked()
+ | {
+ | await _navigationService.Navigate<${entityName}ViewModel>();
+ | }
+ `);
+
+ const rewriteFileModel = this.generateFileModel(entityMenuPath, 'jhipster-needle-add-entity-command', entityEntry);
+
+ this.addBlockContentToFile(rewriteFileModel, errorMessage);
+ }
+
+ addServiceInDI(entityName) {
+ const lowerEntityName = _.toLower(entityName);
+ const errorMessage = `${chalk.yellow('Reference to ') + entityName} ${chalk.yellow('not added to Program.\n')}`;
+ const programPath = `src/${this.mainClientDir}/App.cs`;
+ const serviceEntry =
+ // prettier-ignore
+ this.generator.stripMargin(
+ `|var ${lowerEntityName}Service = new ${entityName}Service(httpClient);
+ | Mvx.IoCProvider.RegisterSingleton(${lowerEntityName}Service);`);
+
+ const rewriteFileModel = this.generateFileModel(programPath, 'jhipster-needle-add-services-in-di', serviceEntry);
+
+ this.addBlockContentToFile(rewriteFileModel, errorMessage);
+ }
+};
\ No newline at end of file
diff --git a/generators/client/prompts.js b/generators/client/prompts.js
index 9993973c1..825eca375 100644
--- a/generators/client/prompts.js
+++ b/generators/client/prompts.js
@@ -23,6 +23,7 @@ const constants = require('../generator-dotnetcore-constants');
const ANGULAR = baseConstants.SUPPORTED_CLIENT_FRAMEWORKS.ANGULAR;
const REACT = baseConstants.SUPPORTED_CLIENT_FRAMEWORKS.REACT;
const BLAZOR = constants.BLAZOR;
+const XAMARIN = constants.XAMARIN;
module.exports = {
askForClient,
@@ -30,7 +31,8 @@ module.exports = {
function askForClient() {
if (this.existingProject) return;
- const choices = [
+
+ var choices = [
{
value: ANGULAR,
name: 'Angular',
@@ -39,7 +41,7 @@ function askForClient() {
value: REACT,
name: 'React',
},
- {
+ {
value: BLAZOR,
name: '[Alpha] - Blazor (WebAssembly)',
},
@@ -48,6 +50,15 @@ function askForClient() {
name: 'No client',
},
];
+
+ if (this.configOptions.isDebugEnabled) {
+ choices.push(
+ {
+ value: XAMARIN,
+ name: '[Alpha] - Xamarin',
+ },
+ )
+ }
const PROMPT = {
type: 'list',
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/MainActivity.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/MainActivity.cs.ejs
new file mode 100644
index 000000000..94f3a5288
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/MainActivity.cs.ejs
@@ -0,0 +1,47 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Android.Runtime;
+using MvvmCross.Forms.Platforms.Android.Core;
+using MvvmCross.Forms.Platforms.Android.Views;
+using Xamarin.Essentials;
+
+namespace <%= namespace %>.Client.Xamarin.Droid
+{
+ [Activity(Label = "<%= namespace %>", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = false,
+ ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
+ ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
+ public class MainActivity : MvxFormsAppCompatActivity
+ {
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ TabLayoutResource = Resource.Layout.Tabbar;
+ ToolbarResource = Resource.Layout.Toolbar;
+
+ base.OnCreate(savedInstanceState);
+ }
+
+ public override void OnRequestPermissionsResult(int requestCode, string[] permissions,
+ [GeneratedEnum] Permission[] grantResults)
+ {
+ Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
+
+ base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Project.Client.Xamarin.Android.csproj.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Project.Client.Xamarin.Android.csproj.ejs
new file mode 100644
index 000000000..c358a350c
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Project.Client.Xamarin.Android.csproj.ejs
@@ -0,0 +1,123 @@
+
+
+
+ Debug
+ AnyCPU
+ {55206BEA-B1A5-4EF4-8030-A53EE728F481}
+ {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {c9e5eea5-ca05-42a1-839b-61506e0a37df}
+ Library
+ <%= namespace %>.Client.Xamarin.Droid
+ <%= namespace %>.Client.Xamarin.Android
+ True
+ True
+ Resources\Resource.designer.cs
+ Resource
+ Properties\AndroidManifest.xml
+ Resources
+ Assets
+ false
+ v10.0
+ true
+ true
+ Xamarin.Android.Net.AndroidClientHandler
+
+
+
+
+ true
+ portable
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ None
+ false
+ false
+ false
+ false
+
+
+ true
+ portable
+ true
+ bin\Release
+ prompt
+ 4
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 7.1.1
+
+
+ 7.1.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {73C411F6-14CB-4E3A-903B-7B42F8AC1651}
+ <%= namespace %>.Client.Xamarin.Core
+
+
+
+
+ MSBuild:UpdateGeneratedFiles
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Project.Client.Xamarin.Android.csproj.user.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Project.Client.Xamarin.Android.csproj.user.ejs
new file mode 100644
index 000000000..ebe7a20cf
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Project.Client.Xamarin.Android.csproj.user.ejs
@@ -0,0 +1,9 @@
+
+
+
+ pixel_2_pie_9_0_-_api_28
+ pixel_2_pie_9_0_-_api_28
+ Nexus 4
+ MainTheme
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Properties/AndroidManifest.xml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Properties/AndroidManifest.xml.ejs
new file mode 100644
index 000000000..e0526e5bd
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Properties/AndroidManifest.xml.ejs
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Properties/AssemblyInfo.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Properties/AssemblyInfo.cs.ejs
new file mode 100644
index 000000000..cb7b765d9
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Properties/AssemblyInfo.cs.ejs
@@ -0,0 +1,30 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+using Android;
+using Android.App;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("<%= namespace %>.Client.Xamarin.Android")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("<%= namespace %>.Client.Xamarin.Android")]
+[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+// Add some common permissions, these can be removed if not needed
+[assembly: UsesPermission(Manifest.Permission.Internet)]
+[assembly: UsesPermission(Manifest.Permission.WriteExternalStorage)]
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/drawable/menu.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/drawable/menu.png
new file mode 100644
index 000000000..f5ea99cd5
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/drawable/menu.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/drawable/splashscreen.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/drawable/splashscreen.png
new file mode 100644
index 000000000..12697825e
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/drawable/splashscreen.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/SplashScreen.xml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/SplashScreen.xml.ejs
new file mode 100644
index 000000000..12497f5b0
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/SplashScreen.xml.ejs
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/Tabbar.xml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/Tabbar.xml.ejs
new file mode 100644
index 000000000..46746280c
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/Tabbar.xml.ejs
@@ -0,0 +1,13 @@
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/Toolbar.xml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/Toolbar.xml.ejs
new file mode 100644
index 000000000..6f4b93076
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/layout/Toolbar.xml.ejs
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-anydpi-v26/icon.xml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-anydpi-v26/icon.xml.ejs
new file mode 100644
index 000000000..b80dc2ac8
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-anydpi-v26/icon.xml.ejs
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-anydpi-v26/icon_round.xml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-anydpi-v26/icon_round.xml.ejs
new file mode 100644
index 000000000..b80dc2ac8
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-anydpi-v26/icon_round.xml.ejs
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-hdpi/icon.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-hdpi/icon.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-hdpi/icon.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-hdpi/launcher_foreground.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-hdpi/launcher_foreground.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-hdpi/launcher_foreground.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-mdpi/icon.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-mdpi/icon.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-mdpi/icon.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-mdpi/launcher_foreground.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-mdpi/launcher_foreground.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-mdpi/launcher_foreground.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xhdpi/icon.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xhdpi/icon.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xhdpi/icon.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xhdpi/launcher_foreground.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xhdpi/launcher_foreground.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xhdpi/launcher_foreground.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxhdpi/icon.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxhdpi/icon.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxhdpi/icon.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxhdpi/launcher_foreground.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxhdpi/launcher_foreground.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxhdpi/launcher_foreground.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxxhdpi/icon.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxxhdpi/icon.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxxhdpi/icon.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/values/colors.xml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/values/colors.xml.ejs
new file mode 100644
index 000000000..04df87dfc
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/values/colors.xml.ejs
@@ -0,0 +1,8 @@
+
+
+
+ #FFFFFF
+ #3F51B5
+ #303F9F
+ #FF4081
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/values/styles.xml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/values/styles.xml.ejs
new file mode 100644
index 000000000..55a07018a
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/Resources/values/styles.xml.ejs
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/SplashScreenActivity.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/SplashScreenActivity.cs.ejs
new file mode 100644
index 000000000..90e04b28a
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Android/SplashScreenActivity.cs.ejs
@@ -0,0 +1,41 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using MvvmCross.Forms.Platforms.Android.Core;
+using MvvmCross.Forms.Platforms.Android.Views;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core;
+
+namespace <%= namespace %>.Client.Xamarin.Droid
+{
+ [Activity(Label = "<%= namespace %>", MainLauncher = true, NoHistory = true, Icon = "@mipmap/icon", ScreenOrientation = ScreenOrientation.Portrait)]
+ public class SplashScreenActivity : MvxFormsSplashScreenActivity, App, FormsApp>
+ {
+ public SplashScreenActivity()
+ : base(Resource.Layout.SplashScreen)
+ {
+ }
+
+ protected override Task RunAppStartAsync(Bundle bundle)
+ {
+ StartActivity(typeof(MainActivity));
+ return Task.CompletedTask;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/App.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/App.cs.ejs
new file mode 100644
index 000000000..a9d552830
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/App.cs.ejs
@@ -0,0 +1,74 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using Akavache;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+using <%= namespace %>.Client.Xamarin.Core.Services;
+using <%= namespace %>.Client.Xamarin.Core.ViewModels;
+using MvvmCross;
+using MvvmCross.ViewModels;
+using System.Net.Http;
+using System.Reactive.Linq;
+using System.Threading.Tasks;
+using MvvmCross.Logging;
+
+namespace <%= namespace %>.Client.Xamarin.Core
+{
+ public class App : MvxApplication
+ {
+ public override void Initialize()
+ {
+ Akavache.Registrations.Start("<%= namespace %>");
+ var log = Mvx.IoCProvider.Resolve().GetLogFor("<%= namespace %>");
+
+ #if DEBUG
+ HttpClientHandler handler = new HttpClientHandler();
+ handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
+ {
+ if (cert.Issuer.Equals("CN=localhost"))
+ return true;
+ return errors == System.Net.Security.SslPolicyErrors.None;
+ };
+ HttpClient httpClient = new HttpClient(handler);
+ #else
+ HttpClient httpClient = new HttpClient();
+ #endif
+ httpClient.BaseAddress = new Uri(Configuration.BaseUri);
+
+ var authenticationService = new AuthenticationService(httpClient, log);
+ Mvx.IoCProvider.RegisterSingleton(authenticationService);
+ var registerService = new RegisterService(httpClient, log);
+ Mvx.IoCProvider.RegisterSingleton(registerService);
+ // jhipster-needle-add-services-in-di - JHipster will add services in DI
+
+ Mvx.IoCProvider.RegisterSingleton(log);
+ Mvx.IoCProvider.RegisterSingleton(httpClient);
+
+ try
+ {
+ // sync trying to connect before loading home view
+ var token = Task.Run(async () => await BlobCache.Secure.GetObject("token")).Result;
+ Task.Run(async () => await authenticationService.SignIn(token));
+ }
+ catch (Exception ex)
+ {
+ log.ErrorException("Failed to fetch token and auto-login.", ex);
+ }
+
+ RegisterAppStart();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/AssemblyInfo.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/AssemblyInfo.cs.ejs
new file mode 100644
index 000000000..e9c28f8ff
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/AssemblyInfo.cs.ejs
@@ -0,0 +1,18 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using Xamarin.Forms.Xaml;
+
+[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/FormsApp.xaml.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/FormsApp.xaml.cs.ejs
new file mode 100644
index 000000000..055bde2cc
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/FormsApp.xaml.cs.ejs
@@ -0,0 +1,26 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+using Xamarin.Forms;
+
+namespace <%= namespace %>.Client.Xamarin.Core
+{
+ public partial class FormsApp : Application
+ {
+ public FormsApp()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/FormsApp.xaml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/FormsApp.xaml.ejs
new file mode 100644
index 000000000..abd13af82
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/FormsApp.xaml.ejs
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/LinkerPreserve.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/LinkerPreserve.cs.ejs
new file mode 100644
index 000000000..d5b665d18
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/LinkerPreserve.cs.ejs
@@ -0,0 +1,35 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using Akavache.Sqlite3;
+using MvvmCross;
+
+namespace <%= namespace %>.Client.Xamarin.Core
+{
+ ///
+ /// Linker preserve for Akavache (https://github.com/reactiveui/Akavache#handling-xamarin-linker).
+ /// Ensures the Akavache.Sqlite3 dll will not be removed by Xamarin build tools.
+ /// Note: This class file is *required* for iOS to work correctly.
+ ///
+ [Preserve]
+ public static class LinkerPreserve
+ {
+ static LinkerPreserve()
+ {
+ var persistentName = typeof(SQLitePersistentBlobCache).FullName;
+ var encryptedName = typeof(SQLiteEncryptedBlobCache).FullName;
+ }
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/JwtToken.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/JwtToken.cs.ejs
new file mode 100644
index 000000000..b7d51035b
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/JwtToken.cs.ejs
@@ -0,0 +1,24 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+using System.Text.Json.Serialization;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Models
+{
+ public class JwtToken
+ {
+ [JsonPropertyName("id_token")]
+ public string IdToken { get; set; }
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/LoginModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/LoginModel.cs.ejs
new file mode 100644
index 000000000..2dbbfb602
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/LoginModel.cs.ejs
@@ -0,0 +1,23 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+namespace <%= namespace %>.Client.Xamarin.Core.Models
+{
+ public class LoginModel
+ {
+ public string Username { get; set; }
+ public string Password { get; set; }
+ public bool RememberMe { get; set; }
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/RegisterResultRequest.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/RegisterResultRequest.cs.ejs
new file mode 100644
index 000000000..7250e8180
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/RegisterResultRequest.cs.ejs
@@ -0,0 +1,36 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Models
+{
+ public class RegisterResultRequest
+ {
+ public string Type { get; set; }
+
+ public int Status { get; set; }
+
+ public string Detail { get; set; }
+
+ public string Params { get; set; }
+
+ public string Message { get; set; }
+
+ public string TraceId { get; set; }
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/UserModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/UserModel.cs.ejs
new file mode 100644
index 000000000..a3f402912
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/UserModel.cs.ejs
@@ -0,0 +1,36 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+using System;
+using System.Collections.Generic;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Models
+{
+ public class UserModel
+ {
+ public string Id { get; set; }
+ public string Login { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public string Email { get; set; }
+ public string ImageUrl { get; set; }
+ public bool Activated { get; set; }
+ public string LangKey { get; set; }
+ public string CreatedBy { get; set; }
+ public DateTime? CreatedDate { get; set; }
+ public string LastModifiedBy { get; set; }
+ public DateTime? LastModifiedDate { get; set; }
+ public IEnumerable Authorities { get; set; }
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/UserSaveModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/UserSaveModel.cs.ejs
new file mode 100644
index 000000000..87406a800
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Models/UserSaveModel.cs.ejs
@@ -0,0 +1,26 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Models
+{
+ public class UserSaveModel : UserModel
+ {
+ public string Password { get; set; }
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Project.Client.Xamarin.Core.csproj.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Project.Client.Xamarin.Core.csproj.ejs
new file mode 100644
index 000000000..bdbb04aee
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Project.Client.Xamarin.Core.csproj.ejs
@@ -0,0 +1,49 @@
+
+
+
+ netstandard2.0
+ true
+
+
+
+ portable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WelcomeView.xaml
+
+
+ HomeView.xaml
+
+
+ RegisterView.xaml
+
+
+
+
+
+ MSBuild:Compile
+
+
+ MSBuild:UpdateDesignTimeXaml
+
+
+ MSBuild:Compile
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Resources/Strings.Designer.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Resources/Strings.Designer.cs.ejs
new file mode 100644
index 000000000..9f441a10a
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Resources/Strings.Designer.cs.ejs
@@ -0,0 +1,115 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+namespace <%= namespace %>.Client.Xamarin.Core.Resources {
+ using System;
+ using System.Reflection;
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class Strings {
+
+ private static System.Resources.ResourceManager resourceMan;
+
+ private static System.Globalization.CultureInfo resourceCulture;
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Strings() {
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.Equals(null, resourceMan)) {
+ System.Resources.ResourceManager temp = new System.Resources.ResourceManager("<%= namespace %>.Resources.Strings", typeof(Strings).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ public static string Name {
+ get {
+ return ResourceManager.GetString("Name", resourceCulture);
+ }
+ }
+
+ public static string Statistics {
+ get {
+ return ResourceManager.GetString("Statistics", resourceCulture);
+ }
+ }
+
+ public static string Time {
+ get {
+ return ResourceManager.GetString("Time", resourceCulture);
+ }
+ }
+
+ public static string AnotherOption {
+ get {
+ return ResourceManager.GetString("AnotherOption", resourceCulture);
+ }
+ }
+
+ public static string Menu {
+ get {
+ return ResourceManager.GetString("Menu", resourceCulture);
+ }
+ }
+
+ public static string BirthYear {
+ get {
+ return ResourceManager.GetString("BirthYear", resourceCulture);
+ }
+ }
+
+ public static string Gender {
+ get {
+ return ResourceManager.GetString("Gender", resourceCulture);
+ }
+ }
+
+ public static string Yes {
+ get {
+ return ResourceManager.GetString("Yes", resourceCulture);
+ }
+ }
+
+ public static string No {
+ get {
+ return ResourceManager.GetString("No", resourceCulture);
+ }
+ }
+
+ public static string Close {
+ get {
+ return ResourceManager.GetString("Close", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Resources/Strings.resx.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Resources/Strings.resx.ejs
new file mode 100644
index 000000000..af78c09f3
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Resources/Strings.resx.ejs
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Name
+
+
+ Menu
+
+
+ Yes
+
+
+ No
+
+
+ Close
+
+
+ Another option
+
+
+ Birth year
+
+
+ Gender
+
+
+ Statistics
+
+
+ Time
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/AbstractEntityService.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/AbstractEntityService.cs.ejs
new file mode 100644
index 000000000..cc736a637
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/AbstractEntityService.cs.ejs
@@ -0,0 +1,60 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Net.Http.Json;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public class AbstractEntityService : IAbstractEntityService where T : class
+ {
+ private readonly HttpClient _httpClient;
+ private readonly string _baseUrl;
+
+ public AbstractEntityService(HttpClient httpClient, string baseUrl)
+ {
+ _httpClient = httpClient;
+ _baseUrl = baseUrl;
+ }
+
+ public async Task> GetEntities()
+ {
+ return await _httpClient.GetFromJsonAsync>(_baseUrl);
+ }
+
+ public async Task GetEntity(long id)
+ {
+ return await _httpClient.GetFromJsonAsync($"{_baseUrl}/{id}");
+ }
+
+ public async Task CreateEntity(T entity)
+ {
+ await _httpClient.PostAsJsonAsync(_baseUrl, entity);
+ }
+
+ public async Task DeleteEntity(long id)
+ {
+ await _httpClient.DeleteAsync($"{_baseUrl}/{id}");
+ }
+
+ public async Task UpdateEntity(T entity)
+ {
+ await _httpClient.PutAsJsonAsync(_baseUrl, entity);
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/AuthenticationService.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/AuthenticationService.cs.ejs
new file mode 100644
index 000000000..95744dfed
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/AuthenticationService.cs.ejs
@@ -0,0 +1,92 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using System.Net.Http;
+using System.Net.Http.Json;
+using System.Reactive.Linq;
+using System.Threading.Tasks;
+using Akavache;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+using MvvmCross.Logging;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public class AuthenticationService : IAuthenticationService
+ {
+ private const string AuthenticationUrl = "api/authenticate";
+ private const string AccountUrl = "api/account";
+ private const string AuthorizationHeader = "Authorization";
+ private readonly HttpClient _httpClient;
+ private readonly IMvxLog _log;
+
+ public bool IsAuthenticated { get; set; }
+ public UserModel CurrentUser { get; set; }
+ private JwtToken JwtToken { get; set; }
+
+ public AuthenticationService(HttpClient httpClient, IMvxLog log)
+ {
+ _httpClient = httpClient;
+ _log = log;
+ }
+
+ public async Task SignIn(LoginModel loginModel)
+ {
+ var result = await _httpClient.PostAsJsonAsync(AuthenticationUrl, loginModel);
+ if (result.IsSuccessStatusCode)
+ {
+ JwtToken = await result.Content.ReadFromJsonAsync();
+ await SetUserAndAuthorizationHeader(JwtToken, loginModel.RememberMe);
+ }
+ return IsAuthenticated;
+ }
+
+ public async Task SignIn(JwtToken jwtToken)
+ {
+ await SetUserAndAuthorizationHeader(jwtToken);
+ return IsAuthenticated;
+ }
+
+ public void SignOut()
+ {
+ _httpClient.DefaultRequestHeaders.Remove(AuthorizationHeader);
+ JwtToken = null;
+ IsAuthenticated = false;
+ CurrentUser = null;
+ BlobCache.Secure.InvalidateAll();
+ }
+
+ private async Task SetUserAndAuthorizationHeader(JwtToken jwtToken, bool save = false)
+ {
+ IsAuthenticated = true;
+ _httpClient.DefaultRequestHeaders.Remove(AuthorizationHeader);
+ _httpClient.DefaultRequestHeaders.Add(AuthorizationHeader, $"Bearer {jwtToken.IdToken}");
+ try
+ {
+ CurrentUser = await _httpClient.GetFromJsonAsync(AccountUrl);
+ if (save)
+ {
+ await BlobCache.Secure.InvalidateAll();
+ await BlobCache.Secure.InsertObject("token", jwtToken);
+ }
+ }
+ catch (Exception ex)
+ {
+ _log.ErrorException("Failed to fetch user and login.", ex);
+ IsAuthenticated = false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/Configuration.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/Configuration.cs.ejs
new file mode 100644
index 000000000..f42aed085
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/Configuration.cs.ejs
@@ -0,0 +1,28 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Xamarin.Forms;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public static class Configuration
+ {
+ public static string BaseUri =
+ Device.RuntimePlatform == Device.Android ? "https://10.0.2.2:5001/" : "https://localhost:5001/";
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IAbstractEntityService.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IAbstractEntityService.cs.ejs
new file mode 100644
index 000000000..c1f2d1319
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IAbstractEntityService.cs.ejs
@@ -0,0 +1,30 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public interface IAbstractEntityService
+ {
+ Task> GetEntities();
+ Task GetEntity(long id);
+ Task DeleteEntity(long id);
+ Task CreateEntity(T entity);
+ Task UpdateEntity(T entity);
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IAuthenticationService.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IAuthenticationService.cs.ejs
new file mode 100644
index 000000000..81ada790d
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IAuthenticationService.cs.ejs
@@ -0,0 +1,29 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System.Net.Http;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public interface IAuthenticationService
+ {
+ bool IsAuthenticated { get; set; }
+ UserModel CurrentUser { get; set; }
+ Task SignIn(LoginModel model);
+ void SignOut();
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IRegisterService.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IRegisterService.cs.ejs
new file mode 100644
index 000000000..62607275f
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/IRegisterService.cs.ejs
@@ -0,0 +1,29 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public interface IRegisterService
+ {
+ Task Save(UserSaveModel registerModel);
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/RegisterService.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/RegisterService.cs.ejs
new file mode 100644
index 000000000..159c02169
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Services/RegisterService.cs.ejs
@@ -0,0 +1,65 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Json;
+using System.Text;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+using MvvmCross.Logging;
+using <%= namespace %>.Client.Xamarin.Shared.Constants;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public class RegisterService : IRegisterService
+ {
+ private const string RegisterUrl = "/api/register";
+ private readonly HttpClient _httpClient;
+ private readonly IMvxLog _log;
+
+ public RegisterService(HttpClient httpClient, IMvxLog log)
+ {
+ _httpClient = httpClient;
+ _log = log;
+ }
+
+ public async Task Save(UserSaveModel registerModel)
+ {
+ var resp = await _httpClient.PostAsJsonAsync(RegisterUrl, registerModel);
+ if (resp.IsSuccessStatusCode)
+ return null;
+ return await ProcessError(resp);
+ }
+
+ private async Task ProcessError(HttpResponseMessage result)
+ {
+ if (result.StatusCode != HttpStatusCode.BadRequest) return ErrorConst.UnknownErrorType;
+
+ try
+ {
+ var res = await result.Content.ReadFromJsonAsync();
+ return res.Type;
+ }
+ catch (Exception ex)
+ {
+ _log.ErrorException("Failed to parse JSON from error", ex);
+ return ErrorConst.UnknownErrorType;
+ }
+ }
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/BaseViewModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/BaseViewModel.cs.ejs
new file mode 100644
index 000000000..b0ecfa859
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/BaseViewModel.cs.ejs
@@ -0,0 +1,29 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using MvvmCross.ViewModels;
+using <%= namespace %>.Client.Xamarin.Core.Resources;
+
+namespace <%= namespace %>.Client.Xamarin.Core.ViewModels
+{
+ public abstract class BaseViewModel : MvxViewModel
+ {
+ ///
+ /// Gets the internationalized string at the given , which is the key of the resource.
+ ///
+ /// Index key of the string from the resources of internationalized strings.
+ public string this[string index] => Strings.ResourceManager.GetString(index);
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/HomeViewModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/HomeViewModel.cs.ejs
new file mode 100644
index 000000000..8a6a4ba26
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/HomeViewModel.cs.ejs
@@ -0,0 +1,47 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Services;
+using MvvmCross.Commands;
+using MvvmCross.Navigation;
+using MvvmCross.ViewModels;
+
+namespace <%= namespace %>.Client.Xamarin.Core.ViewModels
+{
+ public class HomeViewModel : BaseViewModel
+ {
+ private readonly IMvxNavigationService _navigationService;
+
+ public IMvxAsyncCommand ShowMenuViewModelCommand => new MvxAsyncCommand(ShowMenuViewModelCommandClicked);
+ public IMvxAsyncCommand ShowWelcomeViewModelCommand => new MvxAsyncCommand(ShowWelcomeViewModelCommandClicked);
+
+ public HomeViewModel(IMvxNavigationService navigationService)
+ {
+ _navigationService = navigationService;
+ }
+
+ private async Task ShowWelcomeViewModelCommandClicked()
+ {
+ await _navigationService.Navigate();
+ }
+
+ private async Task ShowMenuViewModelCommandClicked()
+ {
+ await _navigationService.Navigate();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/LoginViewModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/LoginViewModel.cs.ejs
new file mode 100644
index 000000000..1accf8379
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/LoginViewModel.cs.ejs
@@ -0,0 +1,131 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+using <%= namespace %>.Client.Xamarin.Core.Services;
+using MvvmCross.Commands;
+using MvvmCross.Navigation;
+using MvvmCross.ViewModels;
+
+namespace <%= namespace %>.Client.Xamarin.Core.ViewModels
+{
+ public class LoginViewModel : BaseViewModel
+ {
+ private readonly IAuthenticationService _authenticationService;
+ private readonly IMvxNavigationService _navigationService;
+
+ private bool _active;
+ private bool _rememberMe;
+ private string _password;
+ private string _username;
+ private bool _success = true;
+
+ public IMvxCommand SignIn => new MvxAsyncCommand(SignInClicked);
+ public IMvxCommand SignUp => new MvxAsyncCommand(SignUpClicked);
+ public IMvxCommand ChangeStateCommand => new MvxCommand(InvertCheckBox);
+
+ public bool Active
+ {
+ get => _active;
+ set
+ {
+ _active = value;
+ RaisePropertyChanged(() => Active);
+ }
+ }
+
+ public string Username
+ {
+ get => _username;
+ set
+ {
+ _username = value;
+ RaisePropertyChanged(() => Username);
+ ReloadActive();
+ }
+ }
+
+ public string Password
+ {
+ get => _password;
+ set
+ {
+ _password = value;
+ RaisePropertyChanged(() => Password);
+ ReloadActive();
+ }
+ }
+
+ public bool RememberMe
+ {
+ get => _rememberMe;
+ set
+ {
+ _rememberMe = value;
+ RaisePropertyChanged(() => RememberMe);
+ }
+ }
+
+ public bool Success
+ {
+ get => _success;
+ set
+ {
+ _success = value;
+ RaisePropertyChanged(() => Success);
+ }
+ }
+
+ public LoginViewModel(IMvxNavigationService navigationService, IAuthenticationService authenticationService)
+ {
+ _navigationService = navigationService;
+ _authenticationService = authenticationService;
+ }
+
+ private void InvertCheckBox()
+ {
+ RememberMe = !RememberMe;
+ }
+
+ private async Task SignUpClicked()
+ {
+ await _navigationService.Navigate();
+ }
+
+ private async Task SignInClicked()
+ {
+ Active = false;
+ Success = await SignInConnection();
+ if (Success) await _navigationService.Navigate();
+ }
+
+ public void ReloadActive()
+ {
+ Active = !string.IsNullOrEmpty(Password) && !string.IsNullOrEmpty(Username) && Password.Length > 3;
+ }
+
+ public Task SignInConnection()
+ {
+ var model = new LoginModel
+ {
+ Username = Username,
+ Password = Password,
+ RememberMe = RememberMe
+ };
+ return _authenticationService.SignIn(model);
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/MenuViewModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/MenuViewModel.cs.ejs
new file mode 100644
index 000000000..446f4c2e5
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/MenuViewModel.cs.ejs
@@ -0,0 +1,65 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using <%= namespace %>.Client.Xamarin.Core.Services;
+using MvvmCross.Commands;
+using MvvmCross.Navigation;
+using System.Threading.Tasks;
+
+namespace <%= namespace %>.Client.Xamarin.Core.ViewModels
+{
+ public class MenuViewModel : BaseViewModel
+ {
+ private readonly IMvxNavigationService _navigationService;
+ private readonly IAuthenticationService _authenticationService;
+
+ public IMvxCommand ShowWelcomeCommand => new MvxAsyncCommand(ShowWelcomeCommandClicked);
+ public IMvxCommand SignIn => new MvxAsyncCommand(SignInClicked);
+ public IMvxCommand SignUp => new MvxAsyncCommand(SignUpClicked);
+ // jhipster-needle-declare-entity-command - JHipster will declare commands
+ public IMvxCommand SignOut => new MvxCommand(SignOutClicked);
+ public bool IsConnected => _authenticationService.IsAuthenticated;
+
+ public MenuViewModel(IMvxNavigationService navigationService, IAuthenticationService authenticationService)
+ {
+ _navigationService = navigationService;
+ _authenticationService = authenticationService;
+ }
+
+ // jhipster-needle-add-entity-command - JHipster will add commands
+
+ private async Task ShowWelcomeCommandClicked()
+ {
+ await _navigationService.Navigate();
+ }
+
+ private async Task SignInClicked()
+ {
+ await _navigationService.Navigate();
+ }
+
+ private async Task SignUpClicked()
+ {
+ await _navigationService.Navigate();
+ }
+
+ private void SignOutClicked()
+ {
+ _authenticationService.SignOut();
+ RaisePropertyChanged(() => IsConnected);
+ _navigationService.Navigate();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/RegisterViewModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/RegisterViewModel.cs.ejs
new file mode 100644
index 000000000..12470db9a
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/RegisterViewModel.cs.ejs
@@ -0,0 +1,206 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+using <%= namespace %>.Client.Xamarin.Core.Services;
+using MvvmCross.Commands;
+using MvvmCross.Navigation;
+using MvvmCross.ViewModels;
+using <%= namespace %>.Client.Xamarin.Shared.Constants;
+using Xamarin.Essentials;
+
+namespace <%= namespace %>.Client.Xamarin.Core.ViewModels
+{
+ public class RegisterViewModel : BaseViewModel
+ {
+ private readonly IAuthenticationService _authenticationService;
+ private readonly IMvxNavigationService _navigationService;
+ private readonly IRegisterService _registerService;
+
+ private bool _active;
+ private bool _rememberMe;
+ private bool _errorMail;
+ private bool _errorLogin;
+ private bool _success;
+ private string _password;
+ private string _username;
+ private string _email;
+ private string _confirmPassword;
+ private bool _error = false;
+
+ public IMvxCommand SignUp => new MvxAsyncCommand(HandleSignUp);
+ public IMvxCommand ChangeStateCommand => new MvxCommand(InvertCheckBox);
+ public IMvxCommand GoBack => new MvxCommand(GoBackClicked);
+
+ public bool Active
+ {
+ get => _active;
+ set
+ {
+ _active = value;
+ RaisePropertyChanged(() => Active);
+ }
+ }
+
+ public string Username
+ {
+ get => _username;
+ set
+ {
+ _username = value;
+ RaisePropertyChanged(() => Username);
+ ReloadActive();
+ }
+ }
+
+ public string Password
+ {
+ get => _password;
+ set
+ {
+ _password = value;
+ RaisePropertyChanged(() => Password);
+ ReloadActive();
+ }
+ }
+
+ public string Email
+ {
+ get => _email;
+ set
+ {
+ _email = value;
+ RaisePropertyChanged(() => Password);
+ ReloadActive();
+ }
+ }
+
+ public bool RememberMe
+ {
+ get => _rememberMe;
+ set
+ {
+ _rememberMe = value;
+ RaisePropertyChanged(() => RememberMe);
+ }
+ }
+
+ public bool Error
+ {
+ get => _error;
+ set
+ {
+ _error = value;
+ RaisePropertyChanged(() => Error);
+ }
+ }
+
+ public string ConfirmPassword
+ {
+ get => _confirmPassword;
+ set
+ {
+ _confirmPassword = value;
+ RaisePropertyChanged(() => ConfirmPassword);
+ ReloadActive();
+ }
+ }
+
+ public bool ErrorMail
+ {
+ get => _errorMail;
+ set
+ {
+ _errorMail = value;
+ RaisePropertyChanged(() => ErrorMail);
+ }
+ }
+
+ public bool ErrorLogin
+ {
+ get => _errorLogin;
+ set
+ {
+ _errorLogin = value;
+ RaisePropertyChanged(() => ErrorLogin);
+ }
+ }
+
+ public bool Success
+ {
+ get => _success;
+ set
+ {
+ _success = value;
+ RaisePropertyChanged(() => Success);
+ }
+ }
+
+ public RegisterViewModel(IMvxNavigationService navigationService, IAuthenticationService authenticationService, IRegisterService registerService)
+ {
+ _navigationService = navigationService;
+ _authenticationService = authenticationService;
+ _registerService = registerService;
+ }
+
+ private void GoBackClicked()
+ {
+ _navigationService.Navigate();
+ }
+
+ private void InvertCheckBox()
+ {
+ RememberMe = !RememberMe;
+ }
+
+ private async Task HandleSignUp()
+ {
+ Active = false;
+ var resultError = await _registerService.Save(new UserSaveModel
+ {
+ Password = Password,
+ Login = Username,
+ Email = Email,
+ LangKey = "en"
+ });
+
+ Error = resultError == ErrorConst.UnknownErrorType;
+ ErrorLogin = resultError == ErrorConst.LoginAlreadyUsedType;
+ ErrorMail = resultError == ErrorConst.EmailAlreadyUsedType;
+
+ Success = (!new List() { Error, ErrorLogin, ErrorMail }.Contains(true));
+ }
+
+ private void ReloadActive()
+ {
+ Active = CheckActive();
+ }
+
+ private bool CheckActive()
+ {
+ var fields = new List { Password, ConfirmPassword, Username, Email };
+ if (fields.Any(field => string.IsNullOrEmpty(field))) return false;
+ if (Password.Length < 4) return false;
+ if (ConfirmPassword != Password) return false;
+ if (Email.Length < 5) return false;
+ if (Email.Split('@').Length != 2) return false;
+ if (!Email.Split('@').All(val => val.Length > 0)) return false;
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/WelcomeViewModel.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/WelcomeViewModel.cs.ejs
new file mode 100644
index 000000000..5abe4218a
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/ViewModels/WelcomeViewModel.cs.ejs
@@ -0,0 +1,89 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Services;
+using MvvmCross.Commands;
+using MvvmCross.Navigation;
+using MvvmCross.ViewModels;
+using Xamarin.Essentials;
+using Xamarin.Forms;
+
+namespace <%= namespace %>.Client.Xamarin.Core.ViewModels
+{
+ public class WelcomeViewModel : BaseViewModel
+ {
+ private readonly IMvxNavigationService _navigationService;
+ private readonly IAuthenticationService _authenticationService;
+
+ public IMvxCommand OpenHomepage => new MvxCommand(OpenHomepageClicked);
+ public IMvxCommand OpenStack => new MvxCommand(OpenStackClicked);
+ public IMvxCommand OpenBugTracker => new MvxCommand(OpenBugTrackerClicked);
+ public IMvxCommand OpenChatRoom => new MvxCommand(OpenChatRoomClicked);
+ public IMvxCommand OpenTwitter => new MvxCommand(OpenTwitterClicked);
+ public IMvxCommand OpenGitHub => new MvxCommand(OpenGitHubClicked);
+ public IMvxCommand SignIn => new MvxCommand(SignInClicked);
+ public IMvxCommand SignUp => new MvxCommand(SignUpClicked);
+ public bool IsConnected => _authenticationService.IsAuthenticated;
+ public string Username => (IsConnected) ? _authenticationService.CurrentUser.Login : null;
+
+ public WelcomeViewModel(IMvxNavigationService navigationService, IAuthenticationService authenticationService)
+ {
+ _navigationService = navigationService;
+ _authenticationService = authenticationService;
+ }
+
+ private void OpenHomepageClicked()
+ {
+ Launcher.OpenAsync("https://www.jhipster.tech/");
+ }
+
+ private void OpenStackClicked()
+ {
+ Launcher.OpenAsync("http://stackoverflow.com/tags/jhipster/info");
+ }
+
+ private void OpenBugTrackerClicked()
+ {
+ Launcher.OpenAsync("https://github.com/jhipster/generator-jhipster/issues?state=open");
+ }
+
+ private void OpenChatRoomClicked()
+ {
+ Launcher.OpenAsync("https://gitter.im/jhipster/generator-jhipster");
+ }
+
+ private void OpenTwitterClicked()
+ {
+ Launcher.OpenAsync("https://twitter.com/jhipster");
+ }
+
+ private void OpenGitHubClicked()
+ {
+ Launcher.OpenAsync("https://github.com/jhipster/generator-jhipster");
+ }
+
+ private void SignInClicked()
+ {
+ _navigationService.Navigate();
+ }
+
+ private void SignUpClicked()
+ {
+ _navigationService.Navigate();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/HomeView.xaml.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/HomeView.xaml.cs.ejs
new file mode 100644
index 000000000..cd53933bc
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/HomeView.xaml.cs.ejs
@@ -0,0 +1,47 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using <%= namespace %>.Client.Xamarin.Core.ViewModels;
+using MvvmCross.Forms.Presenters.Attributes;
+using MvvmCross.Forms.Views;
+using Xamarin.Forms;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Views
+{
+ [MvxMasterDetailPagePresentation(MasterDetailPosition.Root, WrapInNavigationPage = false, NoHistory = true)]
+ public partial class HomeView : MvxMasterDetailPage
+ {
+ private bool _firstTime = true;
+
+ public HomeView()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnAppearing()
+ {
+ if (_firstTime)
+ {
+ ViewModel.ShowMenuViewModelCommand.Execute(null);
+ ViewModel.ShowWelcomeViewModelCommand.Execute(null);
+
+ _firstTime = false;
+ }
+
+ base.OnAppearing();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/HomeView.xaml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/HomeView.xaml.ejs
new file mode 100644
index 000000000..3c6b03685
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/HomeView.xaml.ejs
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/LoginView.xaml.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/LoginView.xaml.cs.ejs
new file mode 100644
index 000000000..41f6f69b0
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/LoginView.xaml.cs.ejs
@@ -0,0 +1,30 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using <%= namespace %>.Client.Xamarin.Core.ViewModels;
+using MvvmCross.Forms.Presenters.Attributes;
+using MvvmCross.Forms.Views;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Views
+{
+ [MvxMasterDetailPagePresentation(MasterDetailPosition.Detail, WrapInNavigationPage = true, NoHistory = true)]
+ public partial class LoginView : MvxContentPage
+ {
+ public LoginView()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/LoginView.xaml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/LoginView.xaml.ejs
new file mode 100644
index 000000000..56b996d88
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/LoginView.xaml.ejs
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/MenuPage.xaml.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/MenuPage.xaml.cs.ejs
new file mode 100644
index 000000000..20e79c258
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/MenuPage.xaml.cs.ejs
@@ -0,0 +1,41 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using MvvmCross.Forms.Presenters.Attributes;
+using MvvmCross.Forms.Views;
+using <%= namespace %>.Client.Xamarin.Core.ViewModels;
+using System;
+using Xamarin.Forms;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Views
+{
+ [MvxMasterDetailPagePresentation(MasterDetailPosition.Master)]
+ public partial class MenuPage : MvxContentPage
+ {
+ public MenuPage()
+ {
+ InitializeComponent();
+ }
+
+ public void ToggleClicked(object sender, EventArgs e)
+ {
+ if (Parent is MvxMasterDetailPage md && Device.RuntimePlatform != Device.UWP)
+ {
+ md.MasterBehavior = MasterBehavior.Popover;
+ md.IsPresented = !md.IsPresented;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/MenuPage.xaml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/MenuPage.xaml.ejs
new file mode 100644
index 000000000..7bb5cf549
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/MenuPage.xaml.ejs
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/RegisterView.xaml.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/RegisterView.xaml.cs.ejs
new file mode 100644
index 000000000..f52bf0b3b
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/RegisterView.xaml.cs.ejs
@@ -0,0 +1,30 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using <%= namespace %>.Client.Xamarin.Core.ViewModels;
+using MvvmCross.Forms.Presenters.Attributes;
+using MvvmCross.Forms.Views;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Views
+{
+ [MvxMasterDetailPagePresentation(MasterDetailPosition.Detail, WrapInNavigationPage = true, NoHistory = true)]
+ public partial class RegisterView : MvxContentPage
+ {
+ public RegisterView()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/RegisterView.xaml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/RegisterView.xaml.ejs
new file mode 100644
index 000000000..2c2d1207f
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/RegisterView.xaml.ejs
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/WelcomeView.xaml.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/WelcomeView.xaml.cs.ejs
new file mode 100644
index 000000000..395fdce77
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/WelcomeView.xaml.cs.ejs
@@ -0,0 +1,32 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using <%= namespace %>.Client.Xamarin.Core.ViewModels;
+using MvvmCross.Forms.Presenters.Attributes;
+using MvvmCross.Forms.Views;
+using Xamarin.Forms;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Views
+{
+ [MvxMasterDetailPagePresentation(MasterDetailPosition.Detail, WrapInNavigationPage = true, NoHistory = true)]
+ public partial class WelcomeView : MvxContentPage
+ {
+ public WelcomeView()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/WelcomeView.xaml.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/WelcomeView.xaml.ejs
new file mode 100644
index 000000000..2724c442e
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Core/Views/WelcomeView.xaml.ejs
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/.vs/Project.Client.Shared/v16/.suo b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/.vs/Project.Client.Shared/v16/.suo
new file mode 100644
index 000000000..0ed5a0133
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/.vs/Project.Client.Shared/v16/.suo differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/Constants/ErrorConst.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/Constants/ErrorConst.cs.ejs
new file mode 100644
index 000000000..fdcd2036f
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/Constants/ErrorConst.cs.ejs
@@ -0,0 +1,28 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace <%= namespace %>.Client.Xamarin.Shared.Constants
+{
+ public static class ErrorConst
+ {
+ public const string ProblemBaseUrl = "https://www.jhipster.tech/problem";
+ public const string UnknownErrorType = ProblemBaseUrl + "/unknown-error";
+ public const string EmailAlreadyUsedType = ProblemBaseUrl + "/email-already-used";
+ public const string LoginAlreadyUsedType = ProblemBaseUrl + "/login-already-used";
+ }
+}
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/Project.Client.Xamarin.Shared.csproj.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/Project.Client.Xamarin.Shared.csproj.ejs
new file mode 100644
index 000000000..dbdcea46b
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.Shared/Project.Client.Xamarin.Shared.csproj.ejs
@@ -0,0 +1,7 @@
+
+
+
+ netstandard2.0
+
+
+
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/AppDelegate.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/AppDelegate.cs.ejs
new file mode 100644
index 000000000..35864d43b
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/AppDelegate.cs.ejs
@@ -0,0 +1,26 @@
+using Foundation;
+using MvvmCross.Forms.Platforms.Ios.Core;
+using UIKit;
+using <%= namespace %>.Client.Xamarin.Core;
+
+namespace <%= namespace %>.Client.Xamarin.iOS
+{
+ // The UIApplicationDelegate for the application. This class is responsible for launching the
+ // User Interface of the application, as well as listening (and optionally responding) to
+ // application events from iOS.
+ [Register("AppDelegate")]
+ public class AppDelegate : MvxFormsApplicationDelegate, App, FormsApp>
+ {
+ //
+ // This method is invoked when the application has loaded and is ready to run. In this
+ // method you should instantiate the window, load the UI into it and then make the window
+ // visible.
+ //
+ // You have 17 seconds to return from this method, or iOS will terminate your application.
+ //
+ public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
+ {
+ return base.FinishedLaunching(uiApplication, launchOptions);
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 000000000..98f4d035c
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,117 @@
+{
+ "images": [
+ {
+ "scale": "2x",
+ "size": "20x20",
+ "idiom": "iphone",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "3x",
+ "size": "20x20",
+ "idiom": "iphone",
+ "filename": "Icon60.png"
+ },
+ {
+ "scale": "2x",
+ "size": "29x29",
+ "idiom": "iphone",
+ "filename": "Icon58.png"
+ },
+ {
+ "scale": "3x",
+ "size": "29x29",
+ "idiom": "iphone",
+ "filename": "Icon87.png"
+ },
+ {
+ "scale": "2x",
+ "size": "40x40",
+ "idiom": "iphone",
+ "filename": "Icon80.png"
+ },
+ {
+ "scale": "3x",
+ "size": "40x40",
+ "idiom": "iphone",
+ "filename": "Icon120.png"
+ },
+ {
+ "scale": "2x",
+ "size": "60x60",
+ "idiom": "iphone",
+ "filename": "Icon120.png"
+ },
+ {
+ "scale": "3x",
+ "size": "60x60",
+ "idiom": "iphone",
+ "filename": "Icon180.png"
+ },
+ {
+ "scale": "1x",
+ "size": "20x20",
+ "idiom": "ipad",
+ "filename": "Icon20.png"
+ },
+ {
+ "scale": "2x",
+ "size": "20x20",
+ "idiom": "ipad",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "1x",
+ "size": "29x29",
+ "idiom": "ipad",
+ "filename": "Icon29.png"
+ },
+ {
+ "scale": "2x",
+ "size": "29x29",
+ "idiom": "ipad",
+ "filename": "Icon58.png"
+ },
+ {
+ "scale": "1x",
+ "size": "40x40",
+ "idiom": "ipad",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "2x",
+ "size": "40x40",
+ "idiom": "ipad",
+ "filename": "Icon80.png"
+ },
+ {
+ "scale": "1x",
+ "size": "76x76",
+ "idiom": "ipad",
+ "filename": "Icon76.png"
+ },
+ {
+ "scale": "2x",
+ "size": "76x76",
+ "idiom": "ipad",
+ "filename": "Icon152.png"
+ },
+ {
+ "scale": "2x",
+ "size": "83.5x83.5",
+ "idiom": "ipad",
+ "filename": "Icon167.png"
+ },
+ {
+ "scale": "1x",
+ "size": "1024x1024",
+ "idiom": "ios-marketing",
+ "filename": "Icon1024.png"
+ }
+ ],
+ "properties": {},
+ "info": {
+ "version": 1,
+ "author": "xcode"
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png
new file mode 100644
index 000000000..9174c989a
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png
new file mode 100644
index 000000000..9c60a1761
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png
new file mode 100644
index 000000000..448d6efb5
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png
new file mode 100644
index 000000000..8524768f8
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png
new file mode 100644
index 000000000..60a64703c
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png
new file mode 100644
index 000000000..45268a641
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png
new file mode 100644
index 000000000..6a6c77a8b
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png
new file mode 100644
index 000000000..cc7edcf5c
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png
new file mode 100644
index 000000000..1ad04f004
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png
new file mode 100644
index 000000000..2dd52620a
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png
new file mode 100644
index 000000000..b058cae2f
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png
new file mode 100644
index 000000000..02e47a261
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png
new file mode 100644
index 000000000..4954a4bd3
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Entitlements.plist.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Entitlements.plist.ejs
new file mode 100644
index 000000000..e9a3005f7
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Entitlements.plist.ejs
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Info.plist.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Info.plist.ejs
new file mode 100644
index 000000000..3424b45d1
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Info.plist.ejs
@@ -0,0 +1,38 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ MinimumOSVersion
+ 8.0
+ CFBundleDisplayName
+ <%= namespace %>
+ CFBundleIdentifier
+ com.companyname.<%= namespace %>.Client.Xamarin.iOS
+ CFBundleVersion
+ 1.0
+ UILaunchStoryboardName
+ LaunchScreen
+ CFBundleName
+ <%= namespace %>
+ XSAppIconAssets
+ Assets.xcassets/AppIcon.appiconset
+
+
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Main.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Main.cs.ejs
new file mode 100644
index 000000000..77f805750
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Main.cs.ejs
@@ -0,0 +1,29 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+using UIKit;
+
+namespace <%= namespace %>.Client.Xamarin.iOS
+{
+ public class Application
+ {
+ // This is the main entry point of the application.
+ private static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, "AppDelegate");
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Project.Client.Xamarin.iOS.csproj.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Project.Client.Xamarin.iOS.csproj.ejs
new file mode 100644
index 000000000..6857ba8fc
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Project.Client.Xamarin.iOS.csproj.ejs
@@ -0,0 +1,145 @@
+
+
+
+ Debug
+ iPhoneSimulator
+ 8.0.30703
+ 2.0
+ {3B7081C2-69A5-49EF-8280-461B4E03F476}
+ {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {6143fdea-f3c2-4a09-aafa-6e230626515e}
+ Exe
+ <%= namespace %>.Client.Xamarin.iOS
+ Resources
+ <%= namespace %>.Client.Xamarin.iOS
+ true
+ NSUrlSessionHandler
+ automatic
+
+
+ true
+ full
+ false
+ bin\iPhoneSimulator\Debug
+ DEBUG
+ prompt
+ 4
+ x86_64
+ None
+ true
+
+
+ none
+ true
+ bin\iPhoneSimulator\Release
+ prompt
+ 4
+ None
+ x86_64
+
+
+ true
+ full
+ false
+ bin\iPhone\Debug
+ DEBUG
+ prompt
+ 4
+ ARM64
+ iPhone Developer
+ true
+ Entitlements.plist
+ None
+ -all
+
+
+ none
+ true
+ bin\iPhone\Release
+ prompt
+ 4
+ ARM64
+ iPhone Developer
+ Entitlements.plist
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ 7.1.1
+
+
+
+
+
+
+
+ {73C411F6-14CB-4E3A-903B-7B42F8AC1651}
+ <%= namespace %>.Client.Xamarin.Core
+
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Project.Client.Xamarin.iOS.csproj.user.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Project.Client.Xamarin.iOS.csproj.user.ejs
new file mode 100644
index 000000000..472348b90
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Project.Client.Xamarin.iOS.csproj.user.ejs
@@ -0,0 +1,6 @@
+
+
+
+ Appareil distant
+
+
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Properties/AssemblyInfo.cs.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Properties/AssemblyInfo.cs.ejs
new file mode 100644
index 000000000..48c4d1fef
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Properties/AssemblyInfo.cs.ejs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("<%= namespace %>.Client.Xamarin.iOS")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("<%= namespace %>.Client.Xamarin.iOS")]
+[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-568h@2x.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-568h@2x.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-568h@2x.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-Portrait.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-Portrait.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-Portrait.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-Portrait@2x.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-Portrait@2x.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default-Portrait@2x.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default@2x.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default@2x.png
new file mode 100644
index 000000000..a3be78868
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/Default@2x.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/LaunchScreen.storyboard.ejs b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/LaunchScreen.storyboard.ejs
new file mode 100644
index 000000000..a639c2f1a
--- /dev/null
+++ b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/LaunchScreen.storyboard.ejs
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/menu.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/menu.png
new file mode 100644
index 000000000..f5ea99cd5
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/menu.png differ
diff --git a/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/splashscreen.png b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/splashscreen.png
new file mode 100644
index 000000000..12697825e
Binary files /dev/null and b/generators/client/templates/xamarin/src/Project.Client.Xamarin.iOS/Resources/splashscreen.png differ
diff --git a/generators/dotnet.js b/generators/dotnet.js
index 53be1e4c0..92f603fa4 100644
--- a/generators/dotnet.js
+++ b/generators/dotnet.js
@@ -18,6 +18,8 @@
*/
const shelljs = require('shelljs');
const fs = require('fs');
+const { Guid } = require('js-guid');
+const _ = require('lodash');
const chalk = require('chalk');
function exec(cmd, opts = {}) {
@@ -55,6 +57,47 @@ async function slnAdd(solutionFile, projects) {
return exec(`dotnet sln ${solutionFile} add ${projects.join(' ')}`);
}
+async function newSlnAddProj(solutionName, projects) {
+ const solutionFile = fs.readFileSync(`${solutionName}.sln`, 'utf8');
+ const regex = new RegExp(`Project\\("{([^}"]*)}"\\) = .*Core.csproj", "{([^}"]*)}"`, 'g'); // eslint-disable-line quotes
+ const exc = regex.exec(solutionFile);
+ const firstGuid = exc[1];
+ const regexp = RegExp(`Project\\("{[^}"]*}"\\) = "client", "client", "{([^}"]*)}"`, 'g'); // eslint-disable-line quotes
+ const clientDir = regexp.exec(solutionFile)[1];
+ const reg = new RegExp(`Project\\("{[^"]*"\\) = "([^"]*)", "[^"]*`, 'g'); // eslint-disable-line quotes
+ let projectText = '';
+ let dirText = '';
+
+ projects.forEach(project => {
+ const existingProjects = solutionFile.matchAll(reg);
+ let alreadyExist = false;
+ let existingProject = existingProjects.next();
+ while (!existingProject.done && !alreadyExist) {
+ alreadyExist = existingProject.value[1] === project.name;
+ existingProject = existingProjects.next();
+ }
+ if (!alreadyExist) {
+ const randomGuid = _.toUpper(Guid.newGuid());
+ projectText += `\nProject("{${firstGuid}}") = "${project.name}", "${project.path}", "{${randomGuid}}"\nEndProject`;
+ dirText += `\n\t\t{${randomGuid}} = {${clientDir}}`;
+ }
+ });
+
+ const projectRe = new RegExp('MinimumVisualStudioVersion = .*\\D', 'g');
+ const projectFound = solutionFile.match(projectRe);
+ projectText = `${projectFound}${projectText}`;
+ let newBody = solutionFile.replace(projectRe, projectText);
+
+ const dirRe = new RegExp('GlobalSection\\(NestedProjects\\) = .*\\D', 'g');
+ const dirFound = solutionFile.match(dirRe);
+ dirText = `${dirFound}${dirText}`;
+ newBody = newBody.replace(dirRe, dirText);
+
+ if (solutionFile !== newBody) {
+ fs.writeFileSync(`${solutionName}.sln`, newBody);
+ }
+}
+
function installBlazorDependencies() {
if (!libmanIsInstalled()) {
if (shelljs.exec('dotnet tool install -g Microsoft.Web.LibraryManager.Cli').code !== 0) {
@@ -91,6 +134,7 @@ async function restore() {
module.exports = {
hasDotnet,
+ newSlnAddProj,
newSln,
slnAdd,
restore,
diff --git a/generators/entity-client/files-xamarin.js b/generators/entity-client/files-xamarin.js
new file mode 100644
index 000000000..1edf0784d
--- /dev/null
+++ b/generators/entity-client/files-xamarin.js
@@ -0,0 +1,104 @@
+/**
+ * Copyright 2013-2020 the original author or authors from the JHipster project.
+ *
+ * This file is part of the JHipster project, see https://www.jhipster.tech/
+ * for more information.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const constants = require('../generator-dotnetcore-constants');
+
+/* Constants use throughout */
+const CLIENT_SRC_DIR = constants.CLIENT_SRC_DIR;
+const XamarinNeedle = require('../client/needle-api/needle-client-xamarin');
+
+/**
+ * The default is to use a file path string. It implies use of the template method.
+ * For any other config an object { file:.., method:.., template:.. } can be used
+ */
+const files = {
+ xamarinAppModels: [
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client/Models/Model.cs',
+ renameTo: generator => `${generator.mainClientDir}/Models/Entities/${generator.asModel(generator.entityClass)}.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client/ViewModels/EntityViewModel.cs',
+ renameTo: generator => `${generator.mainClientDir}/ViewModels/Entities/${generator.entityClass}ViewModel.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client/Services/EntityService.cs',
+ renameTo: generator =>
+ `${generator.mainClientDir}/Services/Entities/${generator.entityClass}/${generator.entityClass}Service.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client/Services/IEntityService.cs',
+ renameTo: generator =>
+ `${generator.mainClientDir}/Services/Entities/${generator.entityClass}/I${generator.entityClass}Service.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client/Views/EntityView.xaml.cs',
+ renameTo: generator =>
+ `${generator.mainClientDir}/Views/Entities/${generator.entityClass}/${generator.entityClass}View.cs`,
+ },
+ ],
+ },
+ {
+ path: CLIENT_SRC_DIR,
+ templates: [
+ {
+ file: 'Project.Client/Views/EntityView.xaml',
+ renameTo: generator =>
+ `${generator.mainClientDir}/Views/Entities/${generator.entityClass}/${generator.entityClass}View.xaml`,
+ },
+ ],
+ },
+ ],
+};
+
+module.exports = {
+ writeFiles,
+ files,
+};
+
+function writeFiles() {
+ this.writeFilesToDisk(files, this, false, 'xamarin');
+ const xamarinNeedle = new XamarinNeedle(this);
+ xamarinNeedle.addEntityToMenu(this.entityClass);
+ xamarinNeedle.addServiceInDI(this.entityClass);
+ xamarinNeedle.addCommandToMenu(this.entityClass);
+ xamarinNeedle.declareCommandToMenu(this.entityClass);
+}
diff --git a/generators/entity-client/index.js b/generators/entity-client/index.js
index 75698a894..bb4d2d610 100644
--- a/generators/entity-client/index.js
+++ b/generators/entity-client/index.js
@@ -4,8 +4,10 @@ const EntityClientGenerator = require('generator-jhipster/generators/entity-clie
const constants = require('../generator-dotnetcore-constants');
const configureGlobalDotnetcore = require('../utils').configureGlobalDotnetcore;
const writeBlazorFiles = require('./files-blazor').writeFiles;
+const writeXamarinFiles = require('./files-xamarin').writeFiles;
const BLAZOR = constants.BLAZOR;
+const XAMARIN = constants.XAMARIN;
module.exports = class extends EntityClientGenerator {
constructor(args, opts) {
@@ -43,11 +45,19 @@ module.exports = class extends EntityClientGenerator {
},
};
}
+ if (this.clientFramework === XAMARIN) {
+ return {
+ writeFilesDotnetcore() {
+ if (this.skipClient) return;
+ return writeXamarinFiles.call(this);
+ },
+ };
+ }
return super._writing();
}
rebuildClient() {
- if (!this.options['skip-install'] && !this.skipClient && this.clientFramework !== BLAZOR) {
+ if (!this.options['skip-install'] && !this.skipClient && this.clientFramework !== BLAZOR && this.clientFramework !== XAMARIN) {
const done = this.async();
this.log(`\n${chalk.bold.green('Running `webpack:build` to update client app\n')}`);
this.spawnCommand('npm', ['--prefix', `${constants.SERVER_SRC_DIR}${this.mainClientDir}`, 'run', 'webpack:build']).on(
diff --git a/generators/entity-client/templates/xamarin/src/Project.Client/Models/Model.cs.ejs b/generators/entity-client/templates/xamarin/src/Project.Client/Models/Model.cs.ejs
new file mode 100644
index 000000000..bcc1fdd70
--- /dev/null
+++ b/generators/entity-client/templates/xamarin/src/Project.Client/Models/Model.cs.ejs
@@ -0,0 +1,81 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+<%_
+const hasManyToMany = entityClassHasManyToMany;
+const entityTableName = snakeCasedEntityClass;
+const entityClassName = pascalizedEntityClass;
+const entityVariableName = camelCasedEntityClass;
+_%>
+<%_
+let hasEnumField = false;
+fields.forEach(field => {
+ if (field.fieldIsEnum) {
+ hasEnumField = true;
+ }
+ });
+if (hasEnumField) { _%>
+using <%= namespace %>.Crosscutting.Enums;
+<%_ } _%>
+using System;
+using System.Collections.Generic;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Models
+{
+ public class <%= asModel(entityClassName) %>
+ {
+ public long? Id { get; set; }
+ <%_ for (idx in fields){
+ let required = false;
+ const fieldValidate = fields[idx].fieldValidate;
+ const fieldValidateRules = fields[idx].fieldValidateRules;
+ const fieldType = equivalentCSharpType(fields[idx].fieldType);
+ const fieldNamePascalized = fields[idx].fieldNamePascalized;
+ if (fieldValidate === true) {
+ if (fieldValidateRules.includes('required')) {
+ required = true;
+ }
+ }
+ if (required) { _%>
+ [Required]
+ <%_ } _%>
+ <%_ if (fields[idx].fieldIsEnum) { _%>
+ public <%= fields[idx].fieldType %> <%= fieldNamePascalized %> { get; set; }
+ <%_ } else { _%>
+ public <%= fieldType %> <%= fieldNamePascalized %> { get; set; }
+ <%_ } _%>
+ <%_ }
+ for (idx in relationships) {
+ const relationshipType = relationships[idx].relationshipType;
+ const relationshipRequired = relationships[idx].relationshipRequired;
+ const otherEntityNamePascalized = relationships[idx].otherEntityNamePascalized;
+ const relationshipFieldNamePascalizedPlural = relationships[idx].relationshipFieldNamePascalizedPlural;
+ const relationshipFieldNamePascalized = relationships[idx].relationshipFieldNamePascalized;
+ if (relationshipType === 'one-to-one'){_%>
+ public <%= asModel(otherEntityNamePascalized) %> <%= relationshipFieldNamePascalized %> { get; set; }
+ <%_}
+ if(relationshipType === 'one-to-many') { _%>
+ public IList<<%= asModel(otherEntityNamePascalized) %>> <%= relationshipFieldNamePascalizedPlural %> { get; set; } = new List<<%= asModel(otherEntityNamePascalized) %>>();
+ <%_ } else if (relationshipType === 'many-to-one') {
+ if (relationshipRequired) { _%>
+ [Required]
+ <%_ } _%>
+ public <%= asModel(otherEntityNamePascalized) %> <%= relationshipFieldNamePascalized %> { get; set; }
+ <%_ } else if (relationshipType === 'many-to-many') { _%>
+ public IList<<%= asModel(otherEntityNamePascalized) %>> <%= relationshipFieldNamePascalizedPlural %> { get; set; } = new List<<%= asModel(otherEntityNamePascalized) %>>();
+ <%_ } _%>
+
+ <%_ } _%>
+ }
+}
diff --git a/generators/entity-client/templates/xamarin/src/Project.Client/Services/EntityService.cs.ejs b/generators/entity-client/templates/xamarin/src/Project.Client/Services/EntityService.cs.ejs
new file mode 100644
index 000000000..7897515a5
--- /dev/null
+++ b/generators/entity-client/templates/xamarin/src/Project.Client/Services/EntityService.cs.ejs
@@ -0,0 +1,33 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+<%_
+const hasManyToMany = entityClassHasManyToMany;
+const entityTableName = snakeCasedEntityClass;
+const entityClassName = pascalizedEntityClass;
+const entityVariableName = camelCasedEntityClass;
+_%>
+using System.Net.Http;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public class <%= entityClassName %>Service : AbstractEntityService<<%= asModel(entityClassName) %>>,I<%= entityClassName %>Service
+ {
+ public <%= entityClassName %>Service(HttpClient httpClient)
+ : base(httpClient, "/api/<%= kebabCasedEntityClassPlural %>")
+ {
+ }
+ }
+}
diff --git a/generators/entity-client/templates/xamarin/src/Project.Client/Services/IEntityService.cs.ejs b/generators/entity-client/templates/xamarin/src/Project.Client/Services/IEntityService.cs.ejs
new file mode 100644
index 000000000..aea8ee370
--- /dev/null
+++ b/generators/entity-client/templates/xamarin/src/Project.Client/Services/IEntityService.cs.ejs
@@ -0,0 +1,30 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+<%_
+const hasManyToMany = entityClassHasManyToMany;
+const entityTableName = snakeCasedEntityClass;
+const entityClassName = pascalizedEntityClass;
+const entityVariableName = camelCasedEntityClass;
+_%>
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+
+namespace <%= namespace %>.Client.Xamarin.Core.Services
+{
+ public interface I<%= entityClassName %>Service : IAbstractEntityService<<%= asModel(entityClassName) %>>
+ {
+ }
+}
diff --git a/generators/entity-client/templates/xamarin/src/Project.Client/ViewModels/EntityViewModel.cs.ejs b/generators/entity-client/templates/xamarin/src/Project.Client/ViewModels/EntityViewModel.cs.ejs
new file mode 100644
index 000000000..1e271291c
--- /dev/null
+++ b/generators/entity-client/templates/xamarin/src/Project.Client/ViewModels/EntityViewModel.cs.ejs
@@ -0,0 +1,177 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Akavache;
+using <%= namespace %>.Client.Xamarin.Core.Models;
+using <%= namespace %>.Client.Xamarin.Core.Services;
+using MvvmCross.Commands;
+using MvvmCross.Navigation;
+using MvvmCross.ViewModels;
+<%_
+let hasEnumField = false;
+fields.forEach(field => {
+ if (field.fieldIsEnum) {
+ hasEnumField = true;
+ }
+ });
+if (hasEnumField) { _%>
+using <%= namespace %>.Crosscutting.Enums;
+<%_ } _%>
+
+<%_
+const hasManyToMany = entityClassHasManyToMany;
+const entityTableName = snakeCasedEntityClass;
+const entityClassName = pascalizedEntityClass;
+const entityVariableName = camelCasedEntityClass;
+_%>
+
+namespace <%= namespace %>.Client.Xamarin.Core.ViewModels
+{
+ public class <%= entityClassName %>ViewModel : MvxViewModel
+ {
+ private readonly I<%= entityClassName %>Service _<%= entityVariableName %>Service;
+ private readonly IMvxNavigationService _navigationService;
+
+ private <%= asModel(entityClassName) %> _currentElement;
+ private List<<%= asModel(entityClassName) %>> _listElement;
+
+ <%_ for (idx in fields){
+ const fieldType = equivalentCSharpType(fields[idx].fieldType);
+ const fieldNameCamelCased = fields[idx].fieldNameCamelCased;
+ if (fields[idx].fieldIsEnum) { _%>
+ public <%= fields[idx].fieldType %> _<%= fieldNameCamelCased %>;
+ <%_ } else { _%>
+ public <%= fieldType %> _<%= fieldNameCamelCased %>;
+ <%_ } _%>
+ <%_ } _%>
+
+ // Workaround to fix MvvmCross issue where buttons remain disabled with MvxAsyncCommand
+ public IMvxCommand AddCommand => new MvxCommand(async () => await AddCommandClicked());
+ public IMvxCommand RemoveCommand => new MvxCommand(async () => await RemoveCommandClicked());
+ public IMvxCommand EditCommand => new MvxCommand(async () => await EditCommandClicked());
+
+ public List<<%= asModel(entityClassName) %>> ListElement
+ {
+ get => _listElement;
+ set
+ {
+ _listElement = value;
+ RaisePropertyChanged(() => ListElement);
+ }
+ }
+
+ public <%= asModel(entityClassName) %> CurrentElement
+ {
+ get => _currentElement;
+ set
+ {
+ _currentElement = value;
+ if (_currentElement != null)
+ {
+ <%_ for (idx in fields){
+ const fieldNamePascalized = fields[idx].fieldNamePascalized;
+ _%>
+ <%= fieldNamePascalized %> = _currentElement.<%= fieldNamePascalized %>;
+ <%_ } _%>
+ }
+ RaisePropertyChanged(() => CurrentElement);
+ }
+ }
+
+ <%_ for (idx in fields) {
+ const fieldType = equivalentCSharpType(fields[idx].fieldType);
+ const fieldNamePascalized = fields[idx].fieldNamePascalized;
+ const fieldNameCamelCased = fields[idx].fieldNameCamelCased;
+ if (fields[idx].fieldIsEnum) { _%>
+ public <%= fields[idx].fieldType %> <%= fieldNamePascalized %>
+ {
+ get => _<%= fieldNameCamelCased %>;
+ set
+ {
+ _<%= fieldNameCamelCased %> = value;
+ RaisePropertyChanged(() => <%= fieldNamePascalized %>);
+ }
+ }
+ <%_ } else { _%>
+ public <%= fieldType %> <%= fieldNamePascalized %>
+ {
+ get => _<%= fieldNameCamelCased %>;
+ set
+ {
+ _<%= fieldNameCamelCased %> = value;
+ RaisePropertyChanged(() => <%= fieldNamePascalized %>);
+ }
+ }
+ <%_ } _%>
+ <%_ } _%>
+
+ public <%= entityClassName %>ViewModel(IMvxNavigationService navigationService, I<%= entityClassName %>Service <%= entityVariableName %>Service)
+ {
+ _navigationService = navigationService;
+ _<%= entityVariableName %>Service = <%= entityVariableName %>Service;
+ }
+
+ public async Task AddCommandClicked()
+ {
+ var entity = new <%= asModel(entityClassName) %>
+ {
+ <%_ for (idx in fields){
+ const fieldNamePascalized = fields[idx].fieldNamePascalized;
+ _%>
+ <%= fieldNamePascalized %> = <%= fieldNamePascalized %>,
+ <%_ } _%>
+ Id = null
+ };
+
+ await _<%= entityVariableName %>Service.CreateEntity(entity);
+ await RefreshList();
+ }
+
+ public async Task RemoveCommandClicked()
+ {
+ if (CurrentElement.Id.HasValue)
+ {
+ await _<%= entityVariableName %>Service.DeleteEntity(CurrentElement.Id.Value);
+ await RefreshList();
+ } // TODO: Handle errors
+ }
+
+ public async Task EditCommandClicked()
+ {
+ <%_ for (idx in fields){
+ const fieldNamePascalized = fields[idx].fieldNamePascalized;
+ _%>
+ CurrentElement.<%= fieldNamePascalized %> = <%= fieldNamePascalized %>;
+ <%_ } _%>
+ await _<%= entityVariableName %>Service.UpdateEntity(CurrentElement);
+ await RefreshList();
+ }
+
+ public async Task RefreshList()
+ {
+ ListElement = await _<%= entityVariableName %>Service.GetEntities();
+ }
+
+ public override async Task Initialize()
+ {
+ await base.Initialize();
+ await RefreshList();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/entity-client/templates/xamarin/src/Project.Client/Views/EntityView.xaml.cs.ejs b/generators/entity-client/templates/xamarin/src/Project.Client/Views/EntityView.xaml.cs.ejs
new file mode 100644
index 000000000..99af99481
--- /dev/null
+++ b/generators/entity-client/templates/xamarin/src/Project.Client/Views/EntityView.xaml.cs.ejs
@@ -0,0 +1,45 @@
+<%#
+ Copyright 2013-2020 the original author or authors from the JHipster project.
+ This file is part of the JHipster project, see https://www.jhipster.tech/
+ for more information.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-%>
+using <%= namespace %>.Client.Xamarin.Core.ViewModels;
+using MvvmCross.Forms.Presenters.Attributes;
+using MvvmCross.Forms.Views;
+<%_
+let hasEnumField = false;
+fields.forEach(field => {
+ if (field.fieldIsEnum) {
+ hasEnumField = true;
+ }
+ });
+if (hasEnumField) { _%>
+using <%= namespace %>.Crosscutting.Enums;
+<%_ } _%>
+<%_
+const hasManyToMany = entityClassHasManyToMany;
+const entityTableName = snakeCasedEntityClass;
+const entityClassName = pascalizedEntityClass;
+const entityVariableName = camelCasedEntityClass;
+_%>
+
+namespace <%= namespace %>.Client.Xamarin.Core.Views
+{
+ [MvxMasterDetailPagePresentation(MasterDetailPosition.Detail, WrapInNavigationPage = true, NoHistory = true)]
+ public partial class <%= entityClassName %>View : MvxContentPage<<%= entityClassName %>ViewModel>
+ {
+ public <%= entityClassName %>View()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/generators/entity-client/templates/xamarin/src/Project.Client/Views/EntityView.xaml.ejs b/generators/entity-client/templates/xamarin/src/Project.Client/Views/EntityView.xaml.ejs
new file mode 100644
index 000000000..814fd7e18
--- /dev/null
+++ b/generators/entity-client/templates/xamarin/src/Project.Client/Views/EntityView.xaml.ejs
@@ -0,0 +1,60 @@
+
+<%_
+const hasManyToMany = entityClassHasManyToMany;
+const entityTableName = snakeCasedEntityClass;
+const entityClassName = pascalizedEntityClass;
+const entityVariableName = camelCasedEntityClass;
+_%>
+
+
+
+
+
+
+
+
+
+
+
+
+ <%_ for (idx in fields){
+ const fieldType = equivalentCSharpType(fields[idx].fieldType);
+ const fieldNamePascalized = fields[idx].fieldNamePascalized;
+ const fieldNameCamelCased = fields[idx].fieldNameCamelCased;_%>
+
+ <%_
+ if (fields[idx].fieldIsEnum) { _%>
+
+ <%_ } else if (fieldType === 'bool?') { _%>
+
+ <%_ } else if (fieldType === 'DateTime?') { _%>
+
+ <%_ } else { _%>
+ "Numeric" <%_ } else { _%> "Text" <%_ } _%> />
+ <%_ } _%>
+ <%_ } _%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generators/generator-dotnetcore-constants.js b/generators/generator-dotnetcore-constants.js
index fc8ca15b7..c9266f5c7 100644
--- a/generators/generator-dotnetcore-constants.js
+++ b/generators/generator-dotnetcore-constants.js
@@ -10,6 +10,7 @@ const PROJECT_CROSSCUTTING_SUFFIX = '.Crosscutting';
const PROJECT_INFRASTRUCTURE_SUFFIX = '.Infrastructure';
const PROJECT_SERVICE_SUFFIX = '.Domain.Services';
const BLAZOR = 'Blazor';
+const XAMARIN = 'Xamarin';
const constants = {
SERVER_SRC_DIR,
@@ -24,6 +25,7 @@ const constants = {
PROJECT_INFRASTRUCTURE_SUFFIX,
PROJECT_SERVICE_SUFFIX,
BLAZOR,
+ XAMARIN,
};
module.exports = constants;
diff --git a/generators/server/templates/dotnetcore/src/Project/Configuration/MvcStartup.cs.ejs b/generators/server/templates/dotnetcore/src/Project/Configuration/MvcStartup.cs.ejs
index 923d9ef5f..7bfb2f202 100644
--- a/generators/server/templates/dotnetcore/src/Project/Configuration/MvcStartup.cs.ejs
+++ b/generators/server/templates/dotnetcore/src/Project/Configuration/MvcStartup.cs.ejs
@@ -46,7 +46,7 @@ namespace <%= namespace %>.Configuration
options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
});
- <%_ if (!skipClient && clientFramework != "Blazor") { _%>
+ <%_ if (!skipClient && clientFramework !== "Blazor" && clientFramework !== "Xamarin") { _%>
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
@@ -74,7 +74,7 @@ namespace <%= namespace %>.Configuration
app.UseHealthChecks("/health");
- <%_ if (!skipClient && clientFramework != "Blazor") { _%>
+ <%_ if (!skipClient && clientFramework !== "Blazor" && clientFramework !== "Xamarin") { _%>
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
diff --git a/generators/server/templates/dotnetcore/src/Project/Program.cs.ejs b/generators/server/templates/dotnetcore/src/Project/Program.cs.ejs
index 893a32841..8b8e466c7 100644
--- a/generators/server/templates/dotnetcore/src/Project/Program.cs.ejs
+++ b/generators/server/templates/dotnetcore/src/Project/Program.cs.ejs
@@ -93,7 +93,7 @@ namespace <%= namespace %>
})
<%_ } _%>
.UseStartup()
- <%_ if(!skipClient && clientFramework != "Blazor") { _%>
+ <%_ if(!skipClient && clientFramework !== "Blazor" && clientFramework !== "Xamarin") { _%>
.UseWebRoot(Path.Combine(Directory.GetCurrentDirectory(), "ClientApp", "dist"))
<%_ } _%>
.UseSerilog();
diff --git a/generators/server/templates/dotnetcore/src/Project/Project.csproj.ejs b/generators/server/templates/dotnetcore/src/Project/Project.csproj.ejs
index b6801c3f2..d0f64c839 100644
--- a/generators/server/templates/dotnetcore/src/Project/Project.csproj.ejs
+++ b/generators/server/templates/dotnetcore/src/Project/Project.csproj.ejs
@@ -24,7 +24,7 @@
true
Latest
false
-<%_ if(!skipClient && clientFramework != "Blazor") { _%>
+<%_ if(!skipClient && clientFramework !== "Blazor" && clientFramework !== "Xamarin") { %>
ClientApp\
<%_ } _%>
$(DefaultItemExcludes);$(SpaRoot)node_modules\**
@@ -75,7 +75,7 @@
-<%_ if(!skipClient && clientFramework != "Blazor") { _%>
+<%_ if(!skipClient && clientFramework !== "Blazor" && clientFramework !== "Xamarin") { _%>
diff --git a/generators/utils.js b/generators/utils.js
index cc6890835..9a295dde2 100644
--- a/generators/utils.js
+++ b/generators/utils.js
@@ -24,6 +24,7 @@ const constants = require('./generator-dotnetcore-constants');
const SERVER_SRC_DIR = constants.SERVER_SRC_DIR;
const BLAZOR = constants.BLAZOR;
+const XAMARIN = constants.XAMARIN;
module.exports = {
copyI18n,
@@ -103,6 +104,13 @@ function configureGlobalDotnetcore() {
this.sharedClientDir = `client/${this.pascalizedBaseName}.Client.Shared`;
this.clientTestProject = `${this.pascalizedBaseName}.Client${constants.PROJECT_TEST_SUFFIX}`;
}
+ if (this.clientFramework === XAMARIN) {
+ this.mainClientDir = `client/${this.pascalizedBaseName}.Client.Xamarin.Core`;
+ this.sharedClientDir = `client/${this.pascalizedBaseName}.Client.Xamarin.Shared`;
+ this.androidClientDir = `client/${this.pascalizedBaseName}.Client.Xamarin.Android`;
+ this.iOSClientDir = `client/${this.pascalizedBaseName}.Client.Xamarin.iOS`;
+ this.clientTestProject = `${this.pascalizedBaseName}.Client.Xamarin${constants.PROJECT_TEST_SUFFIX}`;
+ }
this.options.outputPathCustomizer = [
paths => (paths ? paths.replace(/^src\/main\/webapp(\/|$)/, `src/${this.mainClientAppDir}$1/`) : paths),
diff --git a/package-lock.json b/package-lock.json
index 032ed8901..8c423a703 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4948,9 +4948,9 @@
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
},
"debug": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
- "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"requires": {
"ms": "2.1.2"
}
@@ -6515,6 +6515,11 @@
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
"integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
},
+ "js-guid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/js-guid/-/js-guid-1.0.0.tgz",
+ "integrity": "sha512-PdPqvtk8tDAcbyOXKnL+NJKVED5FyJwm5HE1N/v9TPD7AeVcJEFFrox7//OJyOYn5Vqtsc1B3Nxm1ntW9TutVQ=="
+ },
"js-object-pretty-print": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/js-object-pretty-print/-/js-object-pretty-print-0.3.0.tgz",
diff --git a/package.json b/package.json
index e234bf94e..b8eca9914 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"gulp-filter": "6.0.0",
"insight": "0.10.3",
"jhipster-core": "7.3.4",
+ "js-guid": "1.0.0",
"js-yaml": "4.0.0",
"lodash": "4.17.20",
"meow": "8.1.0",